Aggiungere notifiche push a un'app web

1. Panoramica

I messaggi push offrono un modo semplice ed efficace per coinvolgere nuovamente gli utenti. In questo codelab, imparerai ad aggiungere notifiche push alla tua app web.

Cosa imparerai a fare

  • Come iscrivere e annullare l'iscrizione di un utente ai messaggi push
  • Come gestire i messaggi push in arrivo
  • Come visualizzare una notifica
  • Come rispondere ai clic sulle notifiche

Che cosa ti serve

  • Chrome 52 o versioni successive
  • Server web per Chrome o il tuo server web preferito
  • Un editor di testo
  • Conoscenza di base di HTML, CSS, JavaScript e Chrome DevTools
  • Il codice campione (vedi Configurazione).

2. Configurazione

Scarica il codice campione

Esistono due modi per ottenere il codice campione per questo codelab:

  • Clona il repository Git:
git clone https://github.com/GoogleChrome/push-notifications.git
  • Scarica il file ZIP:

Se scarichi l'origine come file ZIP, decomprimerai il file per ottenere una cartella principale push-notifications-master.

Installare e verificare il server web

Anche se puoi usare liberamente il tuo server web, questo codelab è progettato per funzionare bene con l'app Server web per Chrome. Se non hai ancora installato l'app, puoi scaricarla dal Chrome Web Store:

Dopo aver installato l'app server web per Chrome, fai clic sulla scorciatoia App nella barra dei preferiti:

946bcaaad66e5c8e.png

Nella finestra Applicazioni, fai clic sull'icona del server web:

9f3c21b2cf6cbfb5.png

Verrà visualizzata la finestra di dialogo riportata di seguito, che ti consente di configurare il server web locale:

73543edeb27c3d6f.png

Fai clic sul pulsante Scegli cartella e seleziona la cartella app all'interno della cartella push-notifications che hai scaricato. In questo modo potrai pubblicare il job in corso tramite l'URL mostrato nella sezione URL server web della finestra di dialogo.

In Opzioni, seleziona la casella accanto a Mostra automaticamente index.html, come mostrato di seguito:

5ac11bca86ce7369.png

Successivamente, arresta e riavvia il server facendo scorrere il pulsante di attivazione/disattivazione Server web: AVVIATO verso sinistra e poi di nuovo verso destra.

d42f87972f9fec24.png

Fai clic sull'URL del server web per visitare il tuo sito nel browser web. Dovresti vedere una pagina simile a questa, anche se la tua versione potrebbe mostrare 127.0.0.1:8887 come indirizzo:

00-push-codelab.png

Aggiorna sempre il service worker

Durante lo sviluppo, è utile assicurarsi che il service worker sia sempre aggiornato e che disponga delle modifiche più recenti.

Per configurare questa funzionalità in Chrome:

  1. Vai alla scheda Push codelab.
  2. Apri DevTools: CTRL+MAIUSC+I su Windows e Linux, Cmd+Opzione+I su macOS.
  3. Seleziona il riquadro Applicazione, fai clic sulla scheda Service worker e seleziona la casella di controllo Aggiorna al ricaricamento. Quando questa casella di controllo è abilitata, il service worker viene aggiornato forzatamente ogni volta che la pagina viene ricaricata.

e7d384fb77885b99.png

3. Registra un service worker

Codice completato

Nella directory app è presente un file vuoto denominato sw.js. Questo file sarà il tuo service worker. Per il momento, può rimanere vuoto. Aggiungerai il codice in un secondo momento.

Innanzitutto, devi registrare questo file come service worker.

La pagina app/index.html viene caricata scripts/main.js. Puoi registrare il tuo service worker in questo file JavaScript.

Aggiungi il codice seguente a scripts/main.js:

if ('serviceWorker' in navigator && 'PushManager' in window) {
  console.log('Service Worker and Push are supported');

  navigator.serviceWorker.register('sw.js')
  .then(function(swReg) {
    console.log('Service Worker is registered', swReg);

    swRegistration = swReg;
  })
  .catch(function(error) {
    console.error('Service Worker Error', error);
  });
} else {
  console.warn('Push messaging is not supported');
  pushButton.textContent = 'Push Not Supported';
}

Questo codice verifica se i service worker e i messaggi push sono supportati dal browser. Se sono supportati, il codice registra il file sw.js.

Prova

Verifica le modifiche aggiornando la scheda Codelab push nel browser.

Cerca un Service Worker is registered message nella console in Chrome DevTools, ad esempio:

5d7ad383d6f235d5.png

Recupero chiavi server applicazioni

Per lavorare con questo codelab, devi generare chiavi server delle applicazioni. Puoi farlo sul sito complementare: web-push-codelab.glitch.me

Qui puoi generare una coppia di chiavi pubblica e privata.

push-codelab-04-companion.png

Copia la tua chiave pubblica in scripts/main.js sostituendo il valore <Your Public Key>:

const applicationServerPublicKey = '<Your Public Key>';

Importante: non dovresti mai inserire la tua chiave privata nell'app web.

4. Inizializza stato

Codice completato

Al momento, il pulsante Attiva dell'app web è disattivato e non è possibile fare clic. Questo perché è buona norma disattivare il pulsante push per impostazione predefinita e attivarlo dopo aver verificato che la messaggistica push è supportata dal browser e puoi verificare se l'utente è attualmente iscritto o meno alla messaggistica.

Dovrai creare due funzioni in scripts/main.js:

  • initializeUI, per verificare se l'utente è attualmente iscritto
  • updateBtn, per attivare il pulsante e modificarne il testo a seconda che l'utente sia iscritto o meno.

Aggiungi una funzione initializeUI a main.js in questo modo:

function initializeUI() {
  // Set the initial subscription value
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    isSubscribed = !(subscription === null);

    if (isSubscribed) {
      console.log('User IS subscribed.');
    } else {
      console.log('User is NOT subscribed.');
    }

    updateBtn();
  });
}

Il nuovo metodo utilizza swRegistration del passaggio precedente, recupera la proprietà pushManager da questo e chiama getSubscription().

pushManager. getSubscription() restituisce una promessa che si risolve con l'abbonamento attuale, se presente. In caso contrario, restituisce null. In questo modo, puoi verificare se l'utente è già iscritto, impostare il valore isSubscribed e quindi chiamare updateBtn() per aggiornare il pulsante.

Aggiungi la funzione updateBtn() a main.js:

function updateBtn() {
  if (isSubscribed) {
    pushButton.textContent = 'Disable Push Messaging';
  } else {
    pushButton.textContent = 'Enable Push Messaging';
  }

  pushButton.disabled = false;
}

Questa funzione attiva il pulsante e ne modifica il testo a seconda che l'utente sia abbonato o meno.

L'ultima cosa da fare è chiamare initializeUI() quando il tuo service worker è registrato in main.js:

navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
  console.log('Service Worker is registered', swReg);

  swRegistration = swReg;
  initializeUI();
})

Prova

Aggiorna la scheda Push codelab. Dovresti vedere che il pulsante Abilita messaggistica push è abilitato (puoi fare clic su di esso) e che dovresti vedere User is NOT subscribed nella console.

a1553f4a0483d227.png

Man mano che procedi nella parte restante di questo codelab, il testo del pulsante dovrebbe cambiare ogni volta che ti iscrivi o annulli l'iscrizione.

5. Iscrivi l'utente

Codice completato

Al momento, il pulsante Abilita messaggi push non è molto utile. Risolviamo il problema.

Nella funzione initializeUI(), aggiungi un listener di clic per il pulsante:

function initializeUI() {
  pushButton.addEventListener('click', function() {
    pushButton.disabled = true;
    if (isSubscribed) {
      // TODO: Unsubscribe user
    } else {
      subscribeUser();
    }
  });

  // Set the initial subscription value
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    isSubscribed = !(subscription === null);

    updateSubscriptionOnServer(subscription);

    if (isSubscribed) {
      console.log('User IS subscribed.');
    } else {
      console.log('User is NOT subscribed.');
    }

    updateBtn();
  });
}

Quando l'utente fa clic sul pulsante, lo disattivi per assicurarti che l'utente non possa fare clic una seconda volta, in quanto l'iscrizione ai messaggi push può richiedere del tempo.

Quindi, chiamerai subscribeUser() se l'utente non è attualmente iscritto. Per farlo, devi incollare il seguente codice in scripts/main.js:

function subscribeUser() {
  const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
  swRegistration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: applicationServerKey
  })
  .then(function(subscription) {
    console.log('User is subscribed.');

    updateSubscriptionOnServer(subscription);

    isSubscribed = true;

    updateBtn();
  })
  .catch(function(error) {
    console.error('Failed to subscribe the user: ', error);
    updateBtn();
  });
}

Vediamo in dettaglio che cosa fa questo codice e come iscrive l'utente ai messaggi push.

Innanzitutto, prendi la chiave pubblica del server delle applicazioni, che è codificata con accesso sicuro per URL Base64, e la converti in UInt8Array, perché questo è l'input previsto della chiamata subscribe(). La funzione urlB64ToUint8Array() si trova nella parte superiore di scripts/main.js.

Dopo aver convertito il valore, chiama il metodo subscribe() sul pushManager del Service worker, passando la chiave pubblica del server delle applicazioni e il valore userVisibleOnly: true.

const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: applicationServerKey
})

Il parametro userVisibleOnly garantisce che venga visualizzata una notifica ogni volta che viene inviato un messaggio push. Attualmente questo valore è obbligatorio e deve essere true.

La chiamata a subscribe() restituisce una promessa che verrà risolta dopo i seguenti passaggi:

  1. L'utente ha concesso l'autorizzazione a visualizzare le notifiche.
  2. Il browser ha inviato una richiesta di rete a un servizio push per ottenere i dati necessari per generare un PushSubscription.

Se questi passaggi hanno esito positivo, la promessa subscribe() verrà risolta con un PushSubscription. Se l'utente non concede l'autorizzazione o se si verificano problemi durante l'iscrizione dell'utente, la promessa verrà rifiutata con un errore. In questo modo ottieni la seguente catena di promesse nel codelab:

swRegistration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: applicationServerKey
})
.then(function(subscription) {
  console.log('User is subscribed.');

  updateSubscriptionOnServer(subscription);

  isSubscribed = true;

  updateBtn();

})
.catch(function(err) {
  console.log('Failed to subscribe the user: ', err);
  updateBtn();
});

In questo modo ottieni un abbonamento e tratterai l'utente come abbonato oppure rilevi un errore e lo registri nella console. In entrambi gli scenari, chiami updateBtn() per assicurarti che il pulsante venga riattivato e che abbia il testo appropriato.

In un'applicazione reale, la funzione updateSubscriptionOnServer() è la posizione in cui invieresti i dati dell'abbonamento a un backend, ma per il codelab devi semplicemente visualizzare l'abbonamento nella UI. Aggiungi la seguente funzione a scripts/main.js:

function updateSubscriptionOnServer(subscription) {
  // TODO: Send subscription to application server

  const subscriptionJson = document.querySelector('.js-subscription-json');
  const subscriptionDetails =
    document.querySelector('.js-subscription-details');

  if (subscription) {
    subscriptionJson.textContent = JSON.stringify(subscription);
    subscriptionDetails.classList.remove('is-invisible');
  } else {
    subscriptionDetails.classList.add('is-invisible');
  }
}

Prova

Vai alla scheda Push codelab, aggiorna la pagina e fai clic sul pulsante. Dovresti vedere una richiesta di autorizzazione come la seguente:

fcc61267a0194e81.png

Se concedi l'autorizzazione, dovresti vedere User is subscribed registrato nella console. Il testo del pulsante diventerà Disattiva messaggi push e potrai visualizzare l'abbonamento come dati JSON in fondo alla pagina.

5c5505f2ead037c.png

6. Autorizzazione di gestione negata

Codice completato

Una cosa che non hai ancora gestito è cosa succede se l'utente blocca la richiesta di autorizzazione. Questo aspetto richiede una certa considerazione specifica perché se l'utente blocca l'autorizzazione, la tua app web non potrà mostrare di nuovo la richiesta di autorizzazione e non potrà sottoscrivere l'abbonamento. Devi almeno disattivare il pulsante in modo che l'utente sappia che non può essere utilizzato.

Il modo più ovvio per gestire questo scenario è la funzione updateBtn(). Devi solo controllare il valore Notification.permission, in questo modo:

function updateBtn() {
  if (Notification.permission === 'denied') {
    pushButton.textContent = 'Push Messaging Blocked';
    pushButton.disabled = true;
    updateSubscriptionOnServer(null);
    return;
  }

  if (isSubscribed) {
    pushButton.textContent = 'Disable Push Messaging';
  } else {
    pushButton.textContent = 'Enable Push Messaging';
  }

  pushButton.disabled = false;
}

Sai che se l'autorizzazione è denied, l'utente non può iscriversi e non devi fare altro, quindi disattivare definitivamente il pulsante è l'approccio migliore.

Prova

Dal momento che hai già concesso l'autorizzazione per la tua app web dal passaggio precedente, devi fare clic sulla i in un cerchio nella barra dell'URL e modificare l'autorizzazione Notifiche impostandola su Usa un'autorizzazione predefinita globale (Chiedi).

54495592074f10ae.png

Dopo aver modificato questa impostazione, aggiorna la pagina, fai clic sul pulsante Abilita messaggi push e seleziona Blocca nella finestra di dialogo delle autorizzazioni. Il pulsante verrà disattivato e mostrerà il testo Messaggistica push bloccata.

d4cf22468f6defda.png

Grazie a questa modifica, ora puoi iscrivere l'utente, occupandoti dei possibili scenari di autorizzazione.

7. Gestire un evento push

Codice completato

Prima di imparare a inviare un messaggio push dal tuo backend, devi considerare cosa succederà effettivamente quando un utente iscritto riceve un messaggio push.

Quando attivi un messaggio push, il browser lo riceve, determina a quale service worker è destinato il push, lo riattiva e invia un evento push. Devi rimanere in ascolto dell'evento e mostrare una notifica di conseguenza.

Aggiungi il seguente codice al file sw.js:

self.addEventListener('push', function(event) {
  console.log('[Service Worker] Push Received.');
  console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);

  const title = 'Push Codelab';
  const options = {
    body: 'Yay it works.',
    icon: 'images/icon.png',
    badge: 'images/badge.png'
  };

  event.waitUntil(self.registration.showNotification(title, options));
});

Esaminiamo questo codice. Stai ascoltando eventi push nel tuo service worker aggiungendo un listener di eventi:

self.addEventListener('push', ... );

A meno che tu non abbia mai giocato con i web worker, probabilmente self è una novità. In un file del service worker, self fa riferimento al service worker stesso.)

Quando viene ricevuto un messaggio push, viene chiamato il listener di eventi e crei una notifica chiamando showNotification() sulla proprietà registration del service worker. showNotification() richiede un title; puoi anche assegnargli un oggetto options per impostare un corpo del messaggio, un'icona e un badge. Il badge viene utilizzato solo su Android al momento della stesura del testo.

const title = 'Push Codelab';
const options = {
  body: 'Yay it works.',
  icon: 'images/icon.png',
  badge: 'images/badge.png'
};
self.registration.showNotification(title, options);

L'ultimo aspetto da trattare nella gestione degli eventi di push è event.waitUntil(). Questo metodo accetta una promessa per consentire al browser di mantenere attivo e in esecuzione il service worker fino a quando la promessa passata non è stata risolta.

Per semplificare la comprensione del codice riportato sopra, puoi riscriverlo in questo modo:

const notificationPromise = self.registration.showNotification(title, options);
event.waitUntil(notificationPromise);

Dopo aver completato l'evento push, proviamo a testarlo.

Prova

Con la gestione degli eventi push nel service worker, puoi attivare un falso evento push per verificare cosa succede quando viene ricevuto un messaggio.

Nell'app web, iscriviti ai messaggi push e assicurati di visualizzare User IS subscribed nella console. Nel riquadro Application in DevTools, nella scheda Service worker, fai clic sul pulsante Push:

1ee499267eeccd1c.png

Dopo aver fatto clic su Push, dovresti vedere una notifica come la seguente:

379105dfb0ea56d8.png

Nota: se questo passaggio non funziona, prova ad annullare la registrazione del service worker utilizzando il link Annulla registrazione nel riquadro dell'applicazione DevTools, attendi l'arresto del service worker e ricarica la pagina.

8. Clic notifica

Codice completato

Se fai clic su una di queste notifiche, noterai che non succede nulla. Puoi gestire i clic sulle notifiche ascoltando gli eventi notificationclick nel tuo service worker.

Per iniziare, aggiungi un listener notificationclick in sw.js:

self.addEventListener('notificationclick', function(event) {
  console.log('[Service Worker] Notification click received.');

  event.notification.close();

  event.waitUntil(
    clients.openWindow('https://developers.google.com/web')
  );
});

Quando l'utente fa clic sulla notifica, verrà chiamato il listener di eventi notificationclick.

Il codice chiude innanzitutto la notifica su cui è stato fatto clic:

event.notification.close();

Viene aperta una nuova finestra o scheda in cui viene caricato l'URL https://developers.google.com/web. Se vuoi, puoi modificare questa impostazione.

event.waitUntil(
    clients.openWindow('https://developers.google.com/web/')
  );

event.waitUntil() garantisce che il browser non termini il service worker prima della visualizzazione della nuova finestra o scheda.

Prova

Prova ad attivare di nuovo un messaggio push in DevTools e fai clic sulla notifica. Vedrai la notifica chiusa e una nuova scheda aperta.

9. Inviare messaggi push

Hai notato che la tua app web è in grado di mostrare una notifica utilizzando DevTools e hai controllato come chiuderla con un clic. Il passaggio successivo consiste nell'inviare un messaggio push vero e proprio.

Normalmente, ciò richiederebbe l'invio di un abbonamento da una pagina web a un backend. Il backend attiva quindi un messaggio push effettuando una chiamata API all'endpoint nella sottoscrizione.

Questo non rientra nell'ambito di questo codelab, ma puoi utilizzare il sito companion ( web-push-codelab.glitch.me) per attivare un messaggio push effettivo. Incolla l'abbonamento in fondo alla pagina:

bb202867962a0249.png

Incolla quindi questo indirizzo nel sito associato nell'area di testo Abbonamento a cui inviare:

a0dd93bc33a9e8cf.png

In Testo da inviare, aggiungi qualsiasi stringa che vuoi inviare con il messaggio push.

Fai clic sul pulsante Invia messaggio push.

a5e8e89411ec034.png

A questo punto dovresti ricevere un messaggio push. Il testo utilizzato verrà registrato nella console.

f6815a356d4f9aaa.png

Questo dovrebbe darti la possibilità di testare l'invio e la ricezione di dati e di manipolare le notifiche.

L'app complementare è solo un server nodo che utilizza la libreria web-push per inviare messaggi. Vale la pena consultare la pagina web-push-libs org su GitHub per verificare quali librerie sono disponibili per l'invio di messaggi push. che gestisce molti dei dettagli per attivare i messaggi push.

Puoi visualizzare tutto il codice per il sito companion qui.

10. Annulla l'iscrizione dell'utente

Codice completato

Manca solo la possibilità di annullare l'iscrizione di un utente al push. Per farlo devi chiamare unsubscribe() su un PushSubscription.

Torna al file scripts/main.js e modifica il listener di clic pushButton in initializeUI() come segue:

pushButton.addEventListener('click', function() {
  pushButton.disabled = true;
  if (isSubscribed) {
    unsubscribeUser();
  } else {
    subscribeUser();
  }
});

Nota che ora chiamerai una nuova funzione unsubscribeUser(). Questa funzione ti consente di ottenere l'abbonamento attuale e di chiamare unsubscribe(). Aggiungi il seguente codice a scripts/main.js:

function unsubscribeUser() {
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
    if (subscription) {
      return subscription.unsubscribe();
    }
  })
  .catch(function(error) {
    console.log('Error unsubscribing', error);
  })
  .then(function() {
    updateSubscriptionOnServer(null);

    console.log('User is unsubscribed.');
    isSubscribed = false;

    updateBtn();
  });
}

Esaminiamo questa funzione.

Innanzitutto, ottieni l'abbonamento attuale chiamando getSubscription():

swRegistration.pushManager.getSubscription()

Questa operazione restituisce una promessa che si risolve con un PushSubscription, se esistente. altrimenti restituisce null. Se è presente un abbonamento, chiamerai unsubscribe() per quell'abbonamento; di conseguenza, PushSubscription non è valido.

swRegistration.pushManager.getSubscription()
.then(function(subscription) {
  if (subscription) {
    // TODO: Tell application server to delete subscription
    return subscription.unsubscribe();
  }
})
.catch(function(error) {
  console.log('Error unsubscribing', error);
})

Chiamare unsubscribe() restituisce una promessa, poiché il completamento può richiedere del tempo. Restituisci questa promessa, quindi il prossimo then() della catena attende il completamento di unsubscribe(). Aggiungi anche un gestore catch nel caso in cui la chiamata a unsubscribe() generi un errore. Dopodiché, puoi aggiornare la UI.

.then(function() {
  updateSubscriptionOnServer(null);

  console.log('User is unsubscribed.');
  isSubscribed = false;

  updateBtn();
})

Prova

Dovresti essere in grado di premere Abilita messaggi push o Disattiva messaggi push nell'app web: i log mostreranno l'utente che è iscritto e ha annullato l'iscrizione.

81a07119235b53da.png

11. Terminato

Complimenti per aver completato questo codelab.

Questo codelab ti ha mostrato come iniziare ad aggiungere notifiche push alla tua app web. Per scoprire di più su cosa possono fare le notifiche web, consulta questi documenti.

Se desideri implementare le notifiche push sul tuo sito, potrebbe interessarti aggiungere il supporto per browser meno recenti o non conformi agli standard che utilizzano GCM. Scopri di più qui.

Per approfondire

Post del blog pertinenti