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

PushManager.subscribe()

Methode

Abonniert über einen registrierten Service Worker einen Push-Dienst und liefert ein <code>Promise</code> mit einem <code>PushSubscription</code>-Objekt.

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

Signatur

PushManager.prototype.subscribe(options)

Beschreibung

subscribe() ist der zentrale Schritt, um Web-Push-Benachrichtigungen zu aktivieren. Die Methode wird über registration.pushManager eines aktiven Service Workers aufgerufen. Sie fragt – falls noch nicht geschehen – die Benachrichtigungs-Berechtigung beim Nutzer ab, registriert den Browser beim Push-Dienst des Herstellers (z. B. FCM, Mozilla Autopush, Apple Push) und liefert ein PushSubscription-Objekt zurück.

Die Subscription enthält einen Endpoint-URL sowie die öffentlichen Schlüssel p256dh und auth. Diese Daten schickst du an deinen Server. Er nutzt sie später, um über das Web-Push-Protokoll (RFC 8030) verschlüsselte Nachrichten zu senden, die im Service Worker das push-Event auslösen.

In der Praxis sind zwei Optionen Pflicht: userVisibleOnly: true (Chrome und Safari lehnen false ab) und applicationServerKey, also dein öffentlicher VAPID-Schlüssel. Damit weist sich dein Server gegenüber dem Push-Dienst aus. Existiert schon eine Subscription mit demselben Schlüssel, bekommst du diese zurück. Existiert eine mit einem anderen Schlüssel, schlägt der Aufruf fehl.

Parameter

Name Typ Default Beschreibung
$options Object {} Konfigurationsobjekt für das Abonnement mit den folgenden Eigenschaften.
$options.userVisibleOnly boolean false Sichert zu, dass jede Push-Nachricht eine sichtbare Benachrichtigung auslöst. Chrome und Safari verlangen true, sonst wird das Promise mit NotAllowedError abgelehnt.
$options.applicationServerKey string | ArrayBuffer | TypedArray | DataView | null null Öffentlicher VAPID-Schlüssel des Anwendungsservers: ein unkomprimierter P-256-Punkt mit 65 Byte, als Bytes oder als Base64URL-String. Chrome und Safari setzen ihn voraus.

Rückgabewert

Typ
Promise<PushSubscription>
Beschreibung
Erfüllt sich mit einem PushSubscription-Objekt, das endpoint, expirationTime, options sowie die Methoden getKey(), toJSON() und unsubscribe() bereitstellt. Mögliche Ablehnungen: NotAllowedError (Berechtigung verweigert oder userVisibleOnly fehlt), InvalidStateError (kein aktiver Service Worker oder anderer Schlüssel bereits abonniert), InvalidAccessError (ungültiger Schlüssel), AbortError (Push-Dienst nicht erreichbar).

Beispiele

Grundlegendes Abonnement mit VAPID-Schlüssel

// Base64URL-String in Uint8Array umwandeln
const urlBase64ToUint8Array = (base64String) => {
  const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
  const raw = atob(base64);
  return Uint8Array.from([...raw].map((c) => c.charCodeAt(0)));
};

const VAPID_PUBLIC_KEY = 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U';

const subscribeUser = async () => {
  const registration = await navigator.serviceWorker.register('/sw.js');
  await navigator.serviceWorker.ready;

  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
  });

  console.log('Endpoint:', subscription.endpoint);
  return subscription;
};

subscribeUser();
Endpoint: https://fcm.googleapis.com/fcm/send/dXk3...:APA91b...

Per Button-Klick abonnieren und an den Server senden

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

button.addEventListener('click', async () => {
  if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
    console.warn('Push wird von diesem Browser nicht unterstützt.');
    return;
  }

  try {
    const registration = await navigator.serviceWorker.ready;

    // Bestehende Subscription wiederverwenden
    let subscription = await registration.pushManager.getSubscription();
    if (!subscription) {
      subscription = await registration.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'
      });
    }

    await fetch('/api/push/subscriptions', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(subscription)
    });
    console.log('Push-Benachrichtigungen aktiviert.');
  } catch (err) {
    if (err.name === 'NotAllowedError') {
      console.warn('Berechtigung verweigert.');
    } else {
      console.error('Abonnement fehlgeschlagen:', err);
    }
  }
});
Push-Benachrichtigungen aktiviert.

Aufbau der Subscription als JSON

const registration = await navigator.serviceWorker.ready;
const subscription = await registration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'
});

console.log(JSON.stringify(subscription.toJSON(), null, 2));
{ "endpoint": "https://updates.push.services.mozilla.com/wpush/v2/gAAAA...", "expirationTime": null, "keys": { "p256dh": "BNcRdreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7A8u-Ts1XbjhazAkj7I99e8QcYP7DkM", "auth": "tBHItJI5svbpez7KI4CCXg" } }

// Wichtig · Fallstricke

  • Sicherer Kontext: Die Methode steht nur unter HTTPS oder auf localhost zur Verfügung. Außerdem muss ein aktiver Service Worker vorhanden sein. Warte deshalb auf navigator.serviceWorker.ready.
  • Nutzeraktion: Firefox und Safari verlangen, dass die Berechtigungsabfrage durch eine Nutzeraktion ausgelöst wird, etwa einen Klick. Ein Aufruf direkt beim Laden der Seite wird abgelehnt oder vom Browser stumm unterdrückt.
  • Safari/iOS: Auf iOS und iPadOS funktioniert Web Push erst ab Version 16.4 und nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden. Zusätzlich ist ein Web-App-Manifest nötig.
  • Schlüsselwechsel: Gibt es bereits eine Subscription mit einem anderen applicationServerKey, wirft der Aufruf einen InvalidStateError. Rufe vorher subscription.unsubscribe() auf.
  • Stumme Pushes verboten: Mit userVisibleOnly: true musst du im push-Handler immer showNotification() aufrufen. Sonst zeigen Browser eine Ersatzmeldung an oder entziehen die Berechtigung.
  • Sicherheit: Endpoint und Schlüssel sind Zugangsdaten. Speichere sie nur serverseitig, übertrage sie über HTTPS und ordne sie einem authentifizierten Nutzer zu. Der private VAPID-Schlüssel darf nie im Client-Code stehen.
  • Ablauf: Subscriptions können verfallen. Erhält dein Server vom Push-Dienst den Status 404 oder 410, lösche die Subscription und abonniere im Client neu.