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 nel visualizzare una notifica (così come ogni altra operazione possibile).

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 conoscono i service worker è 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 service worker è che hai poco controllo su quando viene eseguito il codice del service worker. Il browser decide quando attivarlo e quando terminarlo. 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 trasmesso 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 rete per i dati e il monitoraggio dell'evento push con analisi potrebbe avere il seguente aspetto:

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. Stiamo anche effettuando una richiesta di rete, ricevendo la risposta e mostrando 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, a intermittenza, viene visualizzata la notifica predefinita. 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);
});

Puoi vedere quanto è facile perdersi.

Ricorda: se vedi questa notifica, controlla le catene 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