Utilizzo di un service worker per gestire le notifiche

Kate Jeffreys
Kate Jeffreys

In questo codelab utilizzerai un service worker per gestire le notifiche. Le istruzioni riportate di seguito presuppongono che tu abbia già familiarità con i service worker e con le nozioni di base per richiedere l'autorizzazione alle notifiche e inviarle. Se hai bisogno di un ripasso sulle notifiche, consulta il codelab Guida introduttiva all'API Notifications. Per saperne di più sui service worker, consulta l'introduzione ai service worker di Matt Gaunt.

Familiarizzare con l'app di esempio e il codice iniziale

Inizia esaminando l'app live nella nuova scheda di Chrome:

  1. Premi "Control+Maiusc+J" (o "Command+Opzione+J" su Mac) per aprire DevTools.
  2. Fai clic sulla scheda Console.

  3. Assicurati che l'opzione Informazioni sia selezionata nel menu a discesa Livelli accanto alla casella Filtro.

  4. Nella console DevTools per la tua app live, dovresti visualizzare un messaggio della console:

    TODO: Implement getRegistration().

    Questo è un messaggio di uno stub di funzione che implementerai in questo codelab.

Ora diamo un'occhiata al codice dell'app di esempio.

  1. Dai un'occhiata a public/index.js:

    • Esistono quattro stub per le funzioni che implementerai: registerServiceWorker, getRegistration, unRegisterServiceWorker e sendNotification.

    • La funzione requestPermission richiede l'autorizzazione dell'utente per inviare notifiche. Se hai completato il codelab Inizia a utilizzare l'API Notifications, noterai che qui viene utilizzata la funzione requestPermission. L'unica differenza è che ora aggiorna anche l'interfaccia utente dopo aver risolto la richiesta di autorizzazione.

    • La funzione updateUI aggiorna tutti i pulsanti e i messaggi dell'app.

    • La funzione initializePage esegue il rilevamento delle funzionalità per la capacità del service worker nel browser e aggiorna l'interfaccia utente dell'app.

    • Lo script attende il caricamento della pagina e poi la inizializza.

  2. Apri public/service-worker.js.

    Come suggerisce il nome, dovrai aggiungere codice all'app per registrare questo file come service worker.

    Sebbene il file non sia ancora in uso dall'app, contiene del codice iniziale che stamperà un messaggio nella console quando il service worker viene attivato.

    Aggiungerai il codice a public/service-worker.js per gestire le notifiche quando il service worker le riceve.

Registra il service worker

In questo passaggio, scriverai il codice che viene eseguito quando l'utente fa clic su Registra service worker nella UI dell'app. Questo codice registrerà public/service-worker.js come service worker.

  1. Apri public/index.js. Sostituisci la funzione registerServiceWorker con il seguente codice:

    // Use the Service Worker API to register a service worker.
    async function registerServiceWorker() {
      await navigator.serviceWorker.register('./service-worker.js')
      updateUI();
    }
    

    Tieni presente che registerServiceWorker utilizza la dichiarazione async function per semplificare la gestione delle promesse. In questo modo puoi await il valore risolto di un Promise. Ad esempio, la funzione precedente attende il risultato della registrazione di un service worker prima di aggiornare la UI. Per saperne di più, consulta await su MDN.

  2. Ora che l'utente può registrare un service worker, puoi ottenere un riferimento all'oggetto di registrazione del service worker. In public/index.js, sostituisci la funzione getRegistration con il seguente codice:

    // Get the current service worker registration.
    function getRegistration() {
      return navigator.serviceWorker.getRegistration();
    }
    

    La funzione precedente utilizza l'API Service Worker per ottenere la registrazione del service worker corrente, se esistente. Rende un po' più comodo ottenere un riferimento alla registrazione del service worker.

  • Per completare la funzionalità di registrazione del service worker, aggiungi il codice per annullare la registrazione del service worker. Sostituisci la funzione unRegisterServiceWorker con il seguente codice:

    // Unregister a service worker, then update the UI.
    async function unRegisterServiceWorker() {
      // Get a reference to the service worker registration.
      let registration = await getRegistration();
      // Await the outcome of the unregistration attempt
      // so that the UI update is not superceded by a
      // returning Promise.
      await registration.unregister();
      updateUI();
    }
    

Nella scheda in cui stai visualizzando l'app live, ricarica la pagina. I pulsanti Registra service worker e Annulla registrazione service worker ora dovrebbero funzionare.

Invia notifiche al service worker

In questo passaggio, scriverai il codice che verrà eseguito quando l'utente fa clic su Invia una notifica nell'interfaccia utente dell'app. Questo codice creerà una notifica, verificherà che un service worker sia registrato e invierà la notifica al service worker utilizzando il metodo postMessage.

Apri public/index.js e sostituisci la funzione sendNotification con il seguente codice:

// Create and send a test notification to the service worker.
async function sendNotification() {
  // Use a random number as part of the notification data
  // (so you can tell the notifications apart during testing!)
  let randy = Math.floor(Math.random() * 100);
  let notification = {
    title: 'Test ' + randy,
    options: { body: 'Test body ' + randy }
  };
  // Get a reference to the service worker registration.
  let registration = await getRegistration();
  // Check that the service worker registration exists.
  if (registration) {
    // Check that a service worker controller exists before
    // trying to access the postMessage method.
    if (navigator.serviceWorker.controller) {
      navigator.serviceWorker.controller.postMessage(notification);
    } else {
      console.log('No service worker controller found. Try a soft reload.');
    }
  }
}

Ecco cosa fa questo codice:

  • sendNotification è una funzione asincrona, quindi puoi utilizzare await per ottenere un riferimento alla registrazione del service worker.

  • Il metodo postMessage del service worker invia i dati dall'app al service worker. Per ulteriori informazioni, consulta la documentazione di MDN su postMessage.

  • Il codice verifica la presenza della proprietà navigator.serviceWorker.controller prima di tentare di accedere alla funzione postMessage. navigator.serviceWorker.controller sarà null se non è presente alcun service worker attivo o se la pagina è stata aggiornata forzatamente (Shift+Ricarica). Per ulteriori informazioni, consulta la documentazione del controller ServiceWorker su MDN.

Gestire le notifiche nel service worker

In questo passaggio, scriverai il codice nel service worker che gestirà i messaggi pubblicati e mostrerà le notifiche all'utente.

Apri public/service-worker.js. Aggiungi il seguente codice alla fine del file:

// Show notification when received
self.addEventListener('message', (event) => {
  let notification = event.data;
  self.registration.showNotification(
    notification.title,
    notification.options
  ).catch((error) => {
    console.log(error);
  });
});

Ecco una breve spiegazione:

  • self è un riferimento al service worker stesso.

  • Anche se ora il service worker gestisce la visualizzazione delle notifiche, l'interfaccia utente principale dell'app è ancora responsabile dell'ottenimento dell'autorizzazione per le notifiche da parte dell'utente. Se l'autorizzazione non viene concessa, la promessa restituita da showNotification viene rifiutata. Il codice riportato sopra utilizza un blocco catch per evitare un errore di rifiuto Promise non rilevato e gestire questo errore in modo più elegante.

Passa al codelab successivo di questa serie: Crea un server di notifiche push.