Start · Sprachen · JavaScript · Referenz · PushManager.getSubscription()

PushManager.getSubscription()

Methode

Liefert ein Promise mit dem bestehenden <code>PushSubscription</code> des Service Workers oder <code>null</code>, falls noch kein Push-Abonnement existiert.

seit JavaScript Baseline 2023: Chrome 42+, Firefox 44+, Edge 17+, Kategorie: webapi

Signatur

PushManager.prototype.getSubscription()

Beschreibung

Mit getSubscription() fragst du beim PushManager einer Service-Worker-Registrierung (registration.pushManager) ab, ob schon ein Push-Abonnement besteht. Das Promise wird mit einem PushSubscription-Objekt erfüllt, das den Endpunkt des Push-Dienstes und die Schlüssel (p256dh, auth) enthält. Besteht kein Abonnement, ist der Wert null.

Die Methode wird typischerweise beim Laden der Seite aufgerufen, um den Zustand der Oberfläche festzulegen (z. B. „Benachrichtigungen aktivieren“ oder „deaktivieren“ anzeigen). Außerdem prüfst du damit, ob der Server das aktuelle Abonnement kennt. Anders als subscribe() fragt getSubscription() niemals nach einer Berechtigung und legt auch kein neues Abonnement an – der Aufruf hat keine Nebenwirkungen.

Die Methode steht sowohl im Fenster-Kontext (über navigator.serviceWorker.ready) als auch im Service Worker selbst (über self.registration.pushManager) zur Verfügung. Letzteres ist z. B. im Event pushsubscriptionchange nützlich.

Rückgabewert

Typ
Promise<PushSubscription | null>
Beschreibung
Ein Promise, das mit dem bestehenden PushSubscription-Objekt erfüllt wird, oder mit null, wenn es kein Abonnement gibt.

Beispiele

Abonnement-Status beim Seitenaufruf prüfen

const pruefePushStatus = async () => {
  if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
    console.log('Push wird nicht unterstützt');
    return;
  }
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.getSubscription();

  if (subscription) {
    console.log('Abonniert:', subscription.endpoint);
  } else {
    console.log('Kein Push-Abonnement vorhanden');
  }
};

pruefePushStatus();
Abonniert: https://fcm.googleapis.com/fcm/send/abc123... // oder Kein Push-Abonnement vorhanden

Vorhandenes Abonnement wiederverwenden, sonst neu anlegen

const VAPID_PUBLIC_KEY = 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U';

const base64ZuUint8 = (base64) => {
  const padding = '='.repeat((4 - (base64.length % 4)) % 4);
  const raw = atob((base64 + padding).replace(/-/g, '+').replace(/_/g, '/'));
  return Uint8Array.from(raw, (c) => c.charCodeAt(0));
};

const holeOderErstelleAbo = async () => {
  const registration = await navigator.serviceWorker.ready;
  let subscription = await registration.pushManager.getSubscription();

  if (!subscription) {
    subscription = await registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: base64ZuUint8(VAPID_PUBLIC_KEY)
    });
  }

  // Abonnement mit dem Server synchronisieren
  await fetch('/api/push/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(subscription)
  });
  return subscription;
};

Abmelden-Button: bestehendes Abonnement kündigen

const button = document.querySelector('#push-abmelden');

button.addEventListener('click', async () => {
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.getSubscription();
  if (!subscription) return;

  const erfolgreich = await subscription.unsubscribe();
  if (erfolgreich) {
    await fetch('/api/push/unsubscribe', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ endpoint: subscription.endpoint })
    });
    console.log('Push-Benachrichtigungen deaktiviert');
  }
});
Push-Benachrichtigungen deaktiviert

// Wichtig · Fallstricke

  • Sicherer Kontext nötig: Die Push-API gibt es nur über HTTPS (oder localhost) und nur mit aktivem Service Worker. navigator.serviceWorker.ready wird erst erfüllt, wenn ein Service Worker aktiv ist.
  • Abonnement ≠ Berechtigung: Auch wenn ein Abonnement existiert, kann der Nutzer die Berechtigung inzwischen entzogen haben. Prüfe zusätzlich Notification.permission oder pushManager.permissionState().
  • Abonnements können ablaufen: subscription.expirationTime beachten und im Service Worker auf pushsubscriptionchange reagieren. Der Endpunkt kann sich ändern, deshalb das Abonnement regelmäßig mit dem Server abgleichen.
  • Safari: Auf iOS/iPadOS gibt es Push erst ab 16.4 und nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden. In privaten Fenstern oder bei gesperrten Benachrichtigungen kann das Promise mit einem Fehler abgelehnt werden. Den Aufruf daher in try/catch einbetten.
  • Der Endpunkt ist ein geheimer Zugangspunkt: Jeder, der ihn und die Schlüssel kennt, kann Nachrichten senden (wenn keine VAPID-Prüfung aktiv ist). Übertrage ihn nur verschlüsselt an deinen eigenen Server.