Notification API

Aus Wikizone
Wechseln zu: Navigation, Suche

Mit der Notification API kann eine Webseite Nachrichten auf Systemebene versenden.

Links

https://stackoverflow.com/questions/32717824/notification-system-using-php-and-mysql Allgmeine Überlegungen kein Push
https://webdamn.com/build-push-notification-system-with-php-mysql/
https://web-push-book.gauntface.com/ // must read

Stichworte

Observer Design Pattern

Übersicht

Schritte in der Übersicht

  1. Subscription
  2. Send Push Message
  3. Handle Push Event

Schritt 1: Subscription

  1. Get permission
  2. Get PushSubscription
  3. Send PushSubscription to Server
  4. Store PushSubscription Details

=> JavaScript PushAPI

https://developer.mozilla.org/en-US/docs/Web/API/Push_API

Aplication Server Keys

Der VAPID Key verifiziert den Server, so dass der Browser später weiß, dass es sich um den echten Server handelt. Eigentlich wird ein Schlüsselpaar generiert s.u.

Schritt 2: Push Message senden

Server -> WebPush Protocol Request -> PushService -> End Device
  • Der Server der eine Nachrichtschicken will schickt diese Standartisiert an einen Push Service.
  • Welche URL dieser hat teilt der Browser im Schritt eins mit.
  • Der PushService schickt diese dann wenn der Browser des Nutzers Online ist an den Nutzer.
  • Der PushService kann Instruktionen entgegennehmen:
    • Lebensdauer einer Push Nachricht - danach wird sie verworfen.
    • Dringlichkeit (der Service entscheidet z.B. bei geringer Batteriekapazität nur Prio-Nachrichten durchzulassen)
    • Topic - Eine Nachricht mit dem selben Topic wie eine alte ersetzt die Alte.

Schritt 3: Push Events auf dem Endgerät

https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
Message kommt an -> Browser spricht mit Service Worker -> Push Event wird aufgelöst.
  • Wenn die Nachricht abgeliefert wurde wird dies dem Service Worker mitgeteilt. Der Service Worker ist eine JavaScript Datei, die der Browser aufrufen und ausführen kann, ohne dass die Webseite aufgerufen werden muss.
  • Innerhalb des Service Workers kann man eine spezielle API aufrufen. Diese ist nur im Service Worker verfügbar.
  • Der ServiceWorker kann ausgeführt werden wenn der Browser geschlossen ist.
  • Im Push Event des Service Worker kann man Hintergrundaufgaben erledigen (Analytics, Seiten Offline Cachen...)

Subscription in Detail

  1. Feature Detection
    1. Check for serviceWoker on navigator
    2. Check for PushManager on window
  2. Register Service Worker
  3. Request Permission

Feature Detection

if (!('serviceWorker' in navigator)) {
    // Service Worker isn't supported on this browser, disable or hide UI.
    return;
  }

  if (!('PushManager' in window)) {
    // Push isn't supported on this browser, disable or hide UI.
    return;
  }

Register Service worker

function registerServiceWorker() {
  return navigator.serviceWorker.register('service-worker.js')
  .then(function(registration) {
    console.log('Service worker successfully registered.');
    return registration;
  })
  .catch(function(err) {
    console.error('Unable to register service worker.', err);
  });
}

Der Code veranlasst den Browser das service-worker.js File vom Server zu laden. Im Hintergrund wird der Browser das enthaltene JS ausführen. Wenn alles klappt wird ein Promise von register(aufgelöst) und gibt die ServiceWorkerRegistration zurück. Diese können wir für den Zugriff auf die PushManager API nutzen.

https://developer.mozilla.org/en-US/docs/Web/API/PushManager

Request Permission

Die API um eine Permission vom User zu bekommen hat sich verändert. Früher hat es über eine Callback Funktion funktioniert jetzt über die Rückgae einer Promise. Daher sollten wir beides implementieren.

function askPermission() {
  return new Promise(function(resolve, reject) {
    const permissionResult = Notification.requestPermission(function(result) {
      resolve(result);
    });

    if (permissionResult) {
      permissionResult.then(resolve, reject);
    }
  })
  .then(function(permissionResult) {
    if (permissionResult !== 'granted') {
      throw new Error('We weren\'t granted permission.');
    }
  });
}

Die Methode Notification.requestPermission() zeigt dem User die Aufforderung.

getPermissionState

requestPermission lockt den Hauptthread, daher ist es sinnvoll zu checken, welchen Permission Status der User im Moment hat.

function getNotificationPermissionState() {
  if (navigator.permissions) {
    return navigator.permissions.query({name: 'notifications'})
    .then((result) => {
      return result.state;
    });
  }

  return new Promise((resolve) => {
    resolve(Notification.permission);
  });
}

Subscribe mit dem PushManager

Service Worker ist registriert und der User hat die Erlaubnis gegeben. Jetzt kann man den User im PushManager registrieren.

function subscribeUserToPush() {
  return getSWRegistration()
  .then(function(registration) {
    const subscribeOptions = {
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(
        'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'
      )
    };

    return registration.pushManager.subscribe(subscribeOptions);
  })
  .then(function(pushSubscription) {
    console.log('Received PushSubscription: ', JSON.stringify(pushSubscription));
    return pushSubscription;
  });
}