Push-Ereignisse

Matt Gaunt

Bisher ging es um das Abonnieren eines Nutzers und das Senden von Push-Nachrichten. Der nächste Schritt besteht darin, diese Push-Nachricht auf dem Gerät des Nutzers zu empfangen und eine Benachrichtigung anzuzeigen (sowie andere Aufgaben, die wir ausführen möchten).

Push-Ereignis

Wenn eine Nachricht empfangen wird, löst dies ein Push-Ereignis in Ihrem Service Worker aus.

Der Code zum Einrichten eines Push-Ereignis-Listeners sollte ähnlich aussehen wie bei jedem anderen Event-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 verrückteste Teil dieses Codes für die meisten Entwickler, die Service Worker noch nicht kennen, ist die Variable self. self wird häufig in Web Workern verwendet, die auch Service Worker sind. self bezieht sich auf den globalen Geltungsbereich, ä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 des Push-Ereignisses prüfen wir, ob Daten vorhanden sind, und geben etwas an die Konsole aus.

Es gibt 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. Dabei 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 ich mit Wichtiges beschäftigt bin, besteht darin, ein Versprechen an die Methode event.waitUntil() weiterzugeben. Auf diese Weise hält der Browser den Service Worker weiter, bis das von Ihnen übergebene Versprechen erfüllt ist.

Bei Push-Ereignissen gibt es die zusätzliche Anforderung, dass du eine Benachrichtigung anzeigen musst, bevor das von dir übergebene Promise beglichen wurde.

Hier ein einfaches Beispiel für die Anzeige einer Benachrichtigung:

self.addEventListener('push', function(event) {
    const promiseChain = self.registration.showNotification('Hello, World.');

    event.waitUntil(promiseChain);
});

Der Aufruf von self.registration.showNotification() ist die Methode, mit der dem Nutzer eine Benachrichtigung angezeigt wird und die ein Versprechen zurückgegeben wird, das nach dem Anzeigen der Benachrichtigung aufgelöst wird.

Um dieses Beispiel so klar wie möglich zu halten, habe ich dieses Versprechen einer Variablen namens promiseChain zugewiesen. Diese wird dann an event.waitUntil() übergeben. Ich weiß, dass dies sehr ausführlich ist, aber ich habe eine Reihe von Problemen gesehen, die aufgrund von Missverständnissen, was an waitUntil() übergeben werden sollte, oder aufgrund von unterbrochenen Promise-Ketten entstanden.

Ein komplizierteres Beispiel mit einer Netzwerkanfrage für Daten und dem Tracking des Push-Ereignisses mit Analysen könnte wie folgt 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 das Promise pushReceivedTracking() zurückgibt. Für dieses Beispiel können wir so tun, als würden wir eine Netzwerkanfrage an unseren Analyseanbieter senden. Wir senden auch eine Netzwerkanfrage, erhalten die Antwort und zeigen eine Benachrichtigung mit den Antwortdaten für den Titel und die Nachricht der Benachrichtigung an.

Wenn wir diese Versprechen mit Promise.all() kombinieren, können wir dafür sorgen, dass der Service Worker aktiv bleibt, während beide Aufgaben ausgeführt werden. Das resultierende Promise wird an event.waitUntil() übergeben. Das bedeutet, dass der Browser wartet, bis beide Versprechen abgeschlossen sind, bevor er prüft, ob eine Benachrichtigung angezeigt wurde, und den Service Worker beendet.

Wir sollten uns Gedanken über waitUntil() und die Verwendung machen. Eines der häufigsten Probleme für Entwickler ist, dass Chrome bei einer falschen oder fehlerhaften Promise-Kette diese Standardbenachrichtigung anzeigt:

Bild der Standardbenachrichtigung in Chrome

Chrome zeigt nur die Benachrichtigung „Diese Website wurde im Hintergrund aktualisiert.“ an, wenn eine Push-Nachricht empfangen wird und das Push-Ereignis im Service Worker keine Benachrichtigung anzeigt, nachdem das an event.waitUntil() übergebene Promise beendet wurde.

Der Hauptgrund dafür, dass Entwickler sich davon erwischen, besteht darin, dass ihr Code häufig self.registration.showNotification() aufruft, aber nicht mit dem zurückgegebenen Versprechen etwas tut. Dies führt ab und zu dazu, dass die Standardbenachrichtigung angezeigt wird. Wenn wir beispielsweise die Rückgabe für self.registration.showNotification() im obigen Beispiel entfernen, besteht das Risiko, 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);
});

Sie sehen, dass es leicht zu übersehen ist.

Nicht vergessen: Wenn du diese Benachrichtigung siehst, solltest du deine Promiseketten und event.waitUntil() prüfen.

Im nächsten Abschnitt sehen wir uns an, wie Sie Benachrichtigungen gestalten und welche Inhalte sich anzeigen lassen.

Weitere Informationen

Code-Labs