Bis hierhin haben wir das Abonnieren eines Nutzers und das Senden einer Push-Nachricht behandelt. Im nächsten Schritt wird diese Push-Nachricht auf dem Gerät des Nutzers empfangen und eine Benachrichtigung angezeigt. Außerdem können weitere Aufgaben ausgeführt werden.
Das Push-Ereignis
Wenn eine Nachricht empfangen wird, wird ein Push-Ereignis in Ihrem Service Worker ausgelöst.
Der Code zum Einrichten eines Push-Ereignis-Listeners sollte in etwa so aussehen wie jeder andere Ereignis-Listener, den Sie in JavaScript schreiben:
self.addEventListener('push', function(event) {
if (event.data) {
console.log('This push event has data: ', event.data.text());
} else {
console.log('This push event has no data.');
}
});
Der seltsamste Teil dieses Codes für die meisten Entwickler, die neu bei Service Workern sind, ist die Variable self. self wird häufig in Web Workern verwendet, zu denen auch Service Worker gehören. self bezieht sich auf den globalen Bereich, ähnlich wie window auf einer Webseite. Bei Web Workern und Service Workern bezieht sich self jedoch auf den Worker selbst.
Im obigen Beispiel kann man sich self.addEventListener() als das Hinzufügen eines Event-Listeners zum Service Worker selbst vorstellen.
Im Beispiel für das Push-Ereignis prüfen wir, ob Daten vorhanden sind, und geben etwas in der Konsole aus.
Es gibt noch andere Möglichkeiten, Daten aus einem Push-Ereignis zu parsen:
// Returns string
event.data.text()
// Parses data as JSON string and returns an Object
event.data.json()
// Returns blob of data
event.data.blob()
// Returns an arrayBuffer
event.data.arrayBuffer()
Die meisten Nutzer verwenden json() oder text(), je nachdem, was sie von ihrer Anwendung erwarten.
In diesem Beispiel wird gezeigt, wie Sie einen Push-Ereignis-Listener hinzufügen und auf Daten zugreifen. Es fehlen jedoch zwei sehr wichtige Funktionen. Es wird keine Benachrichtigung angezeigt und event.waitUntil() wird nicht verwendet.
Warten bis
Eines der Dinge, die Sie über Service Worker wissen sollten, ist, dass Sie wenig Kontrolle darüber haben, wann der Service Worker-Code ausgeführt wird. Der Browser entscheidet, wann er aktiviert und wann er beendet wird. Die einzige Möglichkeit, dem Browser mitzuteilen, dass Sie gerade mit wichtigen Aufgaben beschäftigt sind, besteht darin, ein Promise an die Methode event.waitUntil() zu übergeben. Dadurch wird der Service Worker im Browser so lange ausgeführt, bis das übergebene Promise aufgelöst wurde.
Bei Push-Ereignissen gilt die zusätzliche Anforderung, dass Sie eine Benachrichtigung anzeigen müssen, bevor das übergebene Promise aufgelöst wurde.
Hier ein einfaches Beispiel für das Anzeigen einer Benachrichtigung:
self.addEventListener('push', function(event) {
const promiseChain = self.registration.showNotification('Hello, World.');
event.waitUntil(promiseChain);
});
Durch den Aufruf von self.registration.showNotification() wird dem Nutzer eine Benachrichtigung angezeigt. Es wird ein Promise zurückgegeben, das aufgelöst wird, sobald die Benachrichtigung angezeigt wurde.
Damit dieses Beispiel so klar wie möglich ist, habe ich dieses Promise einer Variablen namens promiseChain zugewiesen. Diese wird dann an event.waitUntil() übergeben. Ich weiß, dass das sehr ausführlich ist, aber ich habe schon eine Reihe von Problemen gesehen, die auf ein Missverständnis darüber zurückzuführen sind, was an waitUntil() übergeben werden sollte, oder auf fehlerhafte Promise-Ketten.
Ein komplexeres Beispiel mit einer Netzwerkanfrage für Daten und dem Tracking des Push-Ereignisses mit Analytics könnte so aussehen:
self.addEventListener('push', function(event) {
const analyticsPromise = pushReceivedTracking();
const pushInfoPromise = fetch('/api/get-more-data')
.then(function(response) {
return response.json();
})
.then(function(response) {
const title = response.data.userName + ' says...';
const message = response.data.message;
return self.registration.showNotification(title, {
body: message
});
});
const promiseChain = Promise.all([
analyticsPromise,
pushInfoPromise
]);
event.waitUntil(promiseChain);
});
Hier rufen wir eine Funktion auf, die ein Promise pushReceivedTracking() zurückgibt. Für dieses Beispiel können wir so tun, als würde es eine Netzwerkanfrage an unseren Analyseanbieter senden. Außerdem stellen wir eine Netzwerkanfrage, rufen die Antwort ab und zeigen eine Benachrichtigung an, wobei die Antwortdaten für den Titel und die Nachricht der Benachrichtigung verwendet werden.
Wir können dafür sorgen, dass der Service Worker aktiv bleibt, während beide Aufgaben ausgeführt werden, indem wir diese Promises mit Promise.all() kombinieren. Das resultierende Promise wird an event.waitUntil() übergeben. Das bedeutet, dass der Browser wartet, bis beide Promises abgeschlossen sind, bevor er prüft, ob eine Benachrichtigung angezeigt wurde, und den Service Worker beendet.
Der Grund, warum wir uns mit waitUntil() und seiner Verwendung beschäftigen sollten, ist, dass eines der häufigsten Probleme, mit denen Entwickler konfrontiert sind, darin besteht, dass Chrome diese „Standardbenachrichtigung“ anzeigt, wenn die Promise-Kette fehlerhaft oder unterbrochen ist:
Chrome zeigt die Benachrichtigung „Diese Website wurde im Hintergrund aktualisiert“ nur an, wenn eine Push-Nachricht empfangen wird und das Push-Ereignis im Service Worker keine Benachrichtigung anzeigt, nachdem das an event.waitUntil() übergebene Promise abgeschlossen wurde.
Der Hauptgrund, warum Entwickler hier Fehler machen, ist, dass ihr Code oft self.registration.showNotification() aufruft, sie aber nichts mit dem zurückgegebenen Promise tun. Dies führt gelegentlich dazu, dass die Standardbenachrichtigung angezeigt wird. Wir könnten beispielsweise die Rückgabe für self.registration.showNotification() im obigen Beispiel entfernen und riskieren, dass diese Benachrichtigung angezeigt wird.
self.addEventListener('push', function(event) {
const analyticsPromise = pushReceivedTracking();
const pushInfoPromise = fetch('/api/get-more-data')
.then(function(response) {
return response.json();
})
.then(function(response) {
const title = response.data.userName + ' says...';
const message = response.data.message;
self.registration.showNotification(title, {
body: message
});
});
const promiseChain = Promise.all([
analyticsPromise,
pushInfoPromise
]);
event.waitUntil(promiseChain);
});
Das kann man leicht übersehen.
Denken Sie daran: Wenn Sie diese Benachrichtigung sehen, prüfen Sie Ihre Promise-Ketten und event.waitUntil().
Im nächsten Abschnitt sehen wir uns an, wie wir Benachrichtigungen gestalten und welche Inhalte wir anzeigen können.
Weitere Informationen
- Web-Push-Benachrichtigungen – Übersicht
- Funktionsweise von Push
- Nutzer abonnieren
- UX für Berechtigungen
- Nachrichten mit Web-Push-Bibliotheken senden
- Web-Push-Protokoll
- Push-Ereignisse verarbeiten
- Benachrichtigung anzeigen
- Benachrichtigungsverhalten
- Häufige Benachrichtigungsmuster
- Häufig gestellte Fragen zu Push-Benachrichtigungen
- Häufige Probleme und Fehler melden