Eventi push

Matt Gaunt

A questo punto, abbiamo trattato l'iscrizione di un utente e l'invio di un messaggio push. Il passaggio successivo consiste nel ricevere questo messaggio push sul dispositivo dell'utente e mostrare una notifica (nonché svolgere qualsiasi altra attività che potremmo voler eseguire).

Evento push

Quando viene ricevuto un messaggio, viene inviato un evento push nel tuo service worker.

Il codice per configurare un gestore di eventi push dovrebbe essere abbastanza simile a qualsiasi altro gestore di eventi scritto in JavaScript:

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.');
    }
});

La parte più strana di questo codice per la maggior parte degli sviluppatori che non hanno dimestichezza con i worker di servizio è la variabile self. self è comunemente utilizzato nei web worker, che sono service worker. self si riferisce allo scopo globale, in modo simile a window in una pagina web. Tuttavia, per i web worker e i service worker, self si riferisce al worker stesso.

Nell'esempio precedente, self.addEventListener() può essere considerato come l'aggiunta di un gestore di eventi al servizio worker stesso.

Nell'esempio di evento push, controlliamo se sono presenti dati e stampiamo qualcosa nella console.

Esistono altri modi per analizzare i dati di un evento push:

// 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()

La maggior parte delle persone utilizza json() o text() a seconda di cosa si aspetta dalla propria applicazione.

Questo esempio mostra come aggiungere un gestore di eventi push e come accedere ai dati, ma manca due funzionalità molto importanti. Non mostra una notifica e non fa uso di event.waitUntil().

Attendi fino a

Una delle cose da capire sui worker di servizio è che hai poco controllo su quando verrà eseguito il codice del worker di servizio. Il browser decide quando riattivarlo e quando interromperlo. L'unico modo per dire al browser "Hey, sono molto impegnato a fare cose importanti" è passare una promessa al metodo event.waitUntil(). In questo modo, il browser manterrà in esecuzione il service worker finché la promessa passata non sarà risolta.

Con gli eventi push, è necessario un requisito aggiuntivo: devi mostrare una notifica prima che la promessa passata sia risolta.

Ecco un esempio di base di visualizzazione di una notifica:

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

    event.waitUntil(promiseChain);
});

La chiamata a self.registration.showNotification() è il metodo che mostra una notifica all'utente e restituisce una promessa che verrà risolta una volta visualizzata la notifica.

Per mantenere questo esempio il più chiaro possibile, ho assegnato questa promessa a una variabile chiamata promiseChain. che viene poi passato a event.waitUntil(). So che è molto verboso, ma ho riscontrato una serie di problemi che si sono verificati a causa di un equivoco su cosa debba essere passato a waitUntil() o a causa di catene di promesse non mantenute.

Un esempio più complicato con una richiesta di dati di rete e il monitoraggio dell'evento push con Analytics potrebbe essere il seguente:

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);
});

Qui chiamiamo una funzione che restituisce una promessa pushReceivedTracking(), che, per l'esempio, possiamo fare finta che effettui una richiesta di rete al nostro fornitore di analisi. Inoltre, effettuiamo una richiesta di rete, riceviamo la risposta e mostriamo una notifica utilizzando i dati delle risposte per il titolo e il messaggio della notifica.

Possiamo assicurarci che il service worker rimanga attivo durante l'esecuzione di entrambe le attività combinando queste promesse con Promise.all(). La promessa risultante viene passata a event.waitUntil() indicando che il browser attenderà il completamento di entrambe le promesse prima di verificare che sia stata visualizzata una notifica e di terminare il servizio worker.

Il motivo per cui dobbiamo preoccuparci di waitUntil() e di come utilizzarlo è che uno dei problemi più comuni che gli sviluppatori devono affrontare è che, quando la catena di promesse è errata o non funziona, Chrome mostra questa notifica "predefinita":

Un'immagine della notifica predefinita in Chrome

Chrome mostrerà la notifica "Questo sito è stato aggiornato in background" solo quando viene ricevuto un messaggio push e l'evento push nel service worker non mostra una notifica al termine della promessa passata a event.waitUntil().

Il motivo principale per cui gli sviluppatori vengono scoperti è che il loro codice spesso chiama self.registration.showNotification(), ma non fa nulla con la promessa che restituisce. Di conseguenza, la notifica predefinita viene visualizzata in modo intermittente. Ad esempio, potremmo rimuovere il ritorno per self.registration.showNotification() nell'esempio riportato sopra e rischiare di visualizzare questa notifica.

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);
});

È facile non accorgersene.

Ricorda: se vedi questa notifica, controlla le catene di promesse e event.waitUntil().

Nella sezione successiva, vedremo cosa possiamo fare per impostare lo stile delle notifiche e quali contenuti possiamo visualizzare.

Passaggi successivi

Codelab