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

PushManager.permissionState()

Methode

Liefert ein Promise, das mit dem aktuellen Push-Berechtigungsstatus (<code>"granted"</code>, <code>"denied"</code> oder <code>"prompt"</code>) aufgelöst wird.

seit JavaScript Baseline 2023: Chrome 42+, Firefox 44+, Safari 16+ Kategorie: webapi

Signatur

PushManager.prototype.permissionState(options)

Beschreibung

permissionState() fragt ab, ob die Seite Push-Nachrichten empfangen darf. Die Methode wird auf dem PushManager einer Service-Worker-Registrierung aufgerufen (registration.pushManager). Sie fragt den Nutzer nicht um Erlaubnis, sondern gibt nur den aktuellen Status zurück.

Mögliche Werte:

  • "granted": Der Nutzer hat Push erlaubt. subscribe() klappt ohne Rückfrage.
  • "denied": Der Nutzer hat Push abgelehnt. subscribe() schlägt fehl.
  • "prompt": Es gibt noch keine Entscheidung. Beim ersten subscribe() erscheint ein Berechtigungsdialog.

Typischer Einsatz: Man prüft vor dem Anmelden, welche Oberfläche man zeigt, etwa einen „Benachrichtigungen aktivieren“-Button, einen Hinweis bei gesperrter Berechtigung oder gar nichts, wenn schon ein Abo besteht. Das options-Objekt sollte zu den Optionen passen, die man später an subscribe() übergibt, vor allem userVisibleOnly: true. Einige Browser werten den Status abhängig von diesen Optionen aus.

Parameter

Name Typ Default Beschreibung
$options Object {} Optionales Objekt mit den gleichen Feldern wie bei PushManager.subscribe(): userVisibleOnly (boolean, gibt an, ob jede Push-Nachricht eine sichtbare Benachrichtigung auslöst) und applicationServerKey (string | ArrayBuffer | TypedArray, öffentlicher VAPID-Schlüssel).

Rückgabewert

Typ
Promise<"granted" | "denied" | "prompt">
Beschreibung
Ein Promise, das mit dem Berechtigungsstatus als String aufgelöst wird. Es wird abgelehnt (z. B. mit NotSupportedError), wenn der Browser die Optionen nicht unterstützt, etwa userVisibleOnly: false in Chrome.

Beispiele

Berechtigungsstatus einfach abfragen

const registration = await navigator.serviceWorker.ready;
const state = await registration.pushManager.permissionState({
  userVisibleOnly: true
});
console.log(`Push-Berechtigung: ${state}`);
Push-Berechtigung: prompt

Oberfläche abhängig vom Status anzeigen

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

const initPushUI = async () => {
  if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
    hinweis.textContent = 'Push wird von diesem Browser nicht unterstützt.';
    return;
  }

  const registration = await navigator.serviceWorker.register('/sw.js');
  const state = await registration.pushManager.permissionState({ userVisibleOnly: true });

  switch (state) {
    case 'granted': {
      const sub = await registration.pushManager.getSubscription();
      pushButton.hidden = Boolean(sub); // schon abonniert → Button ausblenden
      break;
    }
    case 'prompt':
      pushButton.hidden = false;
      break;
    case 'denied':
      pushButton.hidden = true;
      hinweis.textContent = 'Benachrichtigungen sind blockiert. Bitte in den Browser-Einstellungen freigeben.';
      break;
  }
};

initPushUI();

Nur abonnieren, wenn nicht blockiert (mit VAPID-Schlüssel)

const VAPID_PUBLIC_KEY = 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U';

const urlBase64ToUint8Array = (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 subscribeIfAllowed = async () => {
  const registration = await navigator.serviceWorker.ready;
  const options = {
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
  };

  const state = await registration.pushManager.permissionState(options);
  if (state === 'denied') {
    console.warn('Push blockiert – kein Abo möglich.');
    return null;
  }

  // Bei "prompt" erscheint jetzt der Browser-Dialog
  const subscription = await registration.pushManager.subscribe(options);
  await fetch('/api/push/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(subscription)
  });
  return subscription;
};

// Nur nach einer Nutzeraktion aufrufen, z. B. per Klick
document.querySelector('#push-aktivieren')
  .addEventListener('click', subscribeIfAllowed);

// Wichtig · Fallstricke

  • Kein Berechtigungsdialog: permissionState() fragt nur ab. Die eigentliche Anfrage stellt subscribe() oder Notification.requestPermission(), und zwar nur nach einer Nutzeraktion wie einem Klick. Sonst blockieren viele Browser den Dialog oder zeigen ihn nur verkleinert an.
  • Sicherer Kontext nötig: Die Methode gibt es nur über HTTPS (oder localhost) und nur mit einem registrierten Service Worker.
  • userVisibleOnly: Chrome verlangt userVisibleOnly: true. Ohne diese Option kann das Promise mit NotSupportedError abgelehnt werden. Am besten übergibt man immer dieselben Optionen wie bei subscribe().
  • Safari/iOS: Auf iOS und iPadOS gibt es Web Push erst ab 16.4 und nur für Web-Apps, die zum Home-Bildschirm hinzugefügt wurden. Im normalen Safari-Tab fehlt PushManager. Deshalb vorher die Unterstützung prüfen ('PushManager' in window).
  • Alternative: navigator.permissions.query({ name: 'push', userVisibleOnly: true }) liefert den gleichen Status als PermissionStatus. Dieses Objekt meldet mit dem change-Event auch spätere Änderungen. Firefox unterstützt den Namen 'push' dort aber nicht in allen Versionen.
  • Der Status "granted" bedeutet nicht, dass schon ein Abo besteht. Das prüft man mit getSubscription().