Utilizzo di un service worker per gestire le notifiche

Kate Jeffreys
Kate Jeffreys

In questo codelab utilizzerai un worker di servizio per gestire le notifiche. Le istruzioni riportate di seguito presuppongono che tu abbia già dimestichezza con i service worker e con le nozioni di base per richiedere l'autorizzazione di notifica e inviare notifiche. Se hai bisogno di un ripasso sulle notifiche, consulta il codelab Iniziare a utilizzare l'API Notifications. Per scoprire di più sui service worker, consulta l'articolo di Matt Gaunt Introduzione ai service worker.

Remixa l'app di esempio e visualizzala in una nuova scheda

Le notifiche vengono bloccate automaticamente dall'app Glitch incorporata, pertanto non potrai visualizzare l'anteprima dell'app in questa pagina. Ecco cosa fare:

  1. Fai clic su Remix per modificare per rendere il progetto modificabile.
  2. Per visualizzare l'anteprima del sito, premi Visualizza app, quindi premi A schermo intero schermo intero.

Glitch dovrebbe aprirsi in una nuova scheda di Chrome.

Mentre svolgi questo codelab, apporta modifiche al codice nel Glitch incorporato in questa pagina. Aggiorna la nuova scheda con l'app pubblicata per visualizzare le modifiche.

Familiarizzare con l'app di esempio e il codice di avvio

Per iniziare, guarda l'app in tempo reale nella nuova scheda di Chrome:

  1. Premi "Control+Maiusc+J" (o "Comando+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 l'app pubblicata, dovresti vedere 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 in Glitch incorporato in questa pagina.

  1. Nel Glitch incorporato, dai un'occhiata a public/index.js:

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

    • La funzione requestPermission richiede all'utente l'autorizzazione per inviare notifiche. Se hai completato il codelab Inizia a utilizzare l'API Notifications, noterai che qui viene utilizzata la relativa 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 funzionalità del servizio worker nel browser e aggiorna l'interfaccia utente dell'app.

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

  2. In Glitch incorporato, apri public/service-worker.js.

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

    Anche se il file non è ancora in uso dall'app, contiene del codice iniziale che stampa un messaggio nella console quando il service worker viene attivato.

    Aggiungerai del 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 il servizio worker nell'interfaccia utente dell'app. Questo codice registrerà public/service-worker.js come service worker.

  1. Nell'editor Glitch incorporato, 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 indicata sopra attende il risultato della registrazione di un service worker prima di aggiornare l'interfaccia utente. Per ulteriori informazioni, 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 sopra riportata utilizza l'API Service Worker per recuperare la registrazione del service worker corrente, se esistente. Rende un po' più comodo ottenere un riferimento alla registrazione del servizio 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 in tempo reale, ricarica la pagina. I pulsanti Registra service worker e Annulla registrazione del service worker dovrebbero ora funzionare.

Inviare 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 crea una notifica, verifica che un servizio worker sia registrato e poi invia la notifica al servizio worker utilizzando il relativo metodo postMessage.

Nell'editor Glitch incorporato, apri public/index.js e sostituire 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 utilizzarla per ottenere un riferimento alla registrazione del worker del servizio.await

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

  • Il codice controlla 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 codice nel service worker che gestirà i messaggi pubblicati e mostrerà le notifiche all'utente.

Nell'editor Glitch incorporato, 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 servizio worker stesso.

  • Anche se ora è il service worker a gestire la visualizzazione delle notifiche, l'interfaccia utente dell'app principale è 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 gestirlo in modo un po' più elegante.

Se hai riscontrato un problema, visita la pagina glitch.com/edit/#!/codelab-notifications-service-worker-completed per il codice completo.

Vai al prossimo codelab di questa serie: Creare un server di notifiche push.