Codelab: criar um cliente de notificação push

Kate Jeffreys
Kate Jeffreys
Kayce Basques
Kayce Basques

Este codelab mostra, passo a passo, como criar um cliente de notificação push. Ao final do codelab, você terá um cliente que:

  • Inscreve o usuário para receber notificações push.
  • Recebe mensagens push e as exibe como notificações.
  • Cancela a inscrição do usuário nas notificações push.

Este codelab tem como foco ajudar você a aprender na prática e não aborda muitos conceitos. Leia Como o push funciona para aprender mais sobre os conceitos de notificação push.

O código do servidor deste codelab já está completo. Neste codelab, você só vai implementar o cliente. Para saber como implementar um servidor de notificações push, confira o Codelab: criar um servidor de notificações push.

Compatibilidade com navegadores

Este codelab funciona com as seguintes combinações de sistema operacional e navegador:

  • Windows: Chrome, Edge
  • macOS: Chrome, Firefox
  • Android: Chrome, Firefox

Este codelab não funciona com os seguintes sistemas operacionais (ou combinações de sistema operacional e navegador):

  • macOS: Brave, Edge, Safari
  • iOS

Configuração

Configurar a autenticação

Antes de usar as notificações push, você precisa configurar o servidor e o cliente com chaves de autenticação. Consulte Assinar as solicitações do protocolo de push da Web para saber o motivo. Normalmente, os secrets são armazenados em um arquivo .env, como este.

VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Abra public/index.js.
  2. Substitua VAPID_PUBLIC_KEY_VALUE_HERE pelo valor da sua chave pública.

Registrar um service worker

Seu cliente precisa de um service worker para receber e exibir notificações. É melhor registrar o service worker o mais cedo possível. Consulte Receber e exibir as mensagens enviadas como notificações para mais contexto.

  1. Substitua o comentário // TODO add startup logic here pelo seguinte código:

    if ('serviceWorker' in navigator && 'PushManager' in window) {
      navigator.serviceWorker.register('./service-worker.js').then(serviceWorkerRegistration => {
        console.info('Service worker was registered.');
        console.info({serviceWorkerRegistration});
      }).catch(error => {
        console.error('An error occurred while registering the service worker.');
        console.error(error);
      });
      subscribeButton.disabled = false;
    } else {
      console.error('Browser does not support service workers or push messages.');
    }
    
    subscribeButton.addEventListener('click', subscribeButtonHandler);
    unsubscribeButton.addEventListener('click', unsubscribeButtonHandler);
    
  2. No Chrome, abra o console do DevTools.

  3. A mensagem Service worker was registered. vai aparecer no Console.

Solicitar permissão de notificações push

Nunca peça permissão para enviar notificações push no carregamento de página. Em vez disso, a interface precisa perguntar ao usuário se ele quer receber notificações push. Depois que eles confirmarem explicitamente (com um clique em um botão, por exemplo), você poderá iniciar o processo formal para receber a permissão de notificação push do navegador.

  1. Em public/index.js, substitua o comentário // TODO em subscribeButtonHandler() pelo seguinte código:

    // Prevent the user from clicking the subscribe button multiple times.
    subscribeButton.disabled = true;
    const result = await Notification.requestPermission();
    if (result === 'denied') {
      console.error('The user explicitly denied the permission request.');
      return;
    }
    if (result === 'granted') {
      console.info('The user accepted the permission request.');
    }
    
  2. Volte para a guia do app e clique em Subscribe to push. O navegador ou sistema operacional vai perguntar se você quer permitir que o site envie notificações push.

  3. Selecione Permitir (ou a frase equivalente usada pelo navegador ou sistema operacional). No console, você verá uma mensagem indicando se a solicitação foi aceita ou negada.

Inscrever-se nas notificações push

O processo de inscrição envolve a interação com um serviço da Web controlado pelo fornecedor do navegador, chamado de serviço de push. Depois de receber as informações de inscrição de notificação push, você precisa enviá-las a um servidor e fazer com que ele as armazene em um banco de dados de longo prazo.

  1. Adicione o seguinte código destacado a subscribeButtonHandler():

    subscribeButton.disabled = true;
    const result = await Notification.requestPermission();
    if (result === 'denied') {
      console.error('The user explicitly denied the permission request.');
      return;
    }
    if (result === 'granted') {
      console.info('The user accepted the permission request.');
    }
    const registration = await navigator.serviceWorker.getRegistration();
    const subscribed = await registration.pushManager.getSubscription();
    if (subscribed) {
      console.info('User is already subscribed.');
      notifyMeButton.disabled = false;
      unsubscribeButton.disabled = false;
      return;
    }
    const subscription = await registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlB64ToUint8Array(VAPID_PUBLIC_KEY)
    });
    notifyMeButton.disabled = false;
    fetch('/add-subscription', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(subscription)
    });
    

A opção userVisibleOnly precisa ser true. No futuro, talvez seja possível enviar mensagens sem mostrar notificações visíveis ao usuário (push silencioso), mas os navegadores não permitem esse recurso devido a questões de privacidade.

O valor applicationServerKey depende de uma função utilitária que converte uma string base64 em um Uint8Array. Esse valor é usado para autenticação entre o servidor e o serviço de push.

Cancelar inscrição nas notificações push

Depois que um usuário se inscreve para receber notificações push, sua interface precisa oferecer uma maneira de cancelar a inscrição caso o usuário mude de ideia e não queira mais receber notificações push.

  • Substitua o comentário // TODO em unsubscribeButtonHandler() pelo seguinte código:
const registration = await navigator.serviceWorker.getRegistration();
const subscription = await registration.pushManager.getSubscription();
fetch('/remove-subscription', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({endpoint: subscription.endpoint})
});
const unsubscribed = await subscription.unsubscribe();
if (unsubscribed) {
  console.info('Successfully unsubscribed from push notifications.');
  unsubscribeButton.disabled = true;
  subscribeButton.disabled = false;
  notifyMeButton.disabled = true;
}

Receber uma mensagem push e mostrá-la como uma notificação

Como mencionado antes, você precisa de um service worker para processar o recebimento e a exibição de mensagens que foram enviadas ao cliente pelo seu servidor. Consulte Receber e exibir as mensagens enviadas como notificações para mais detalhes.

  1. Abra public/service-worker.js e substitua o comentário // TODO no manipulador de eventos push do service worker pelo seguinte código:

    let data = event.data.json();
    const image = 'logo.png';
    const options = {
      body: data.options.body,
      icon: image
    }
    self.registration.showNotification(
      data.title,
      options
    );
    
  2. Volte para a guia do app.

  3. Clique em Receber notificação. Você vai receber uma notificação push.

  4. Abra o URL da guia do app em outros navegadores compatíveis. Siga o fluxo de trabalho de inscrição e clique em Notificar todos. Você vai receber a mesma notificação push em cada um.

É possível personalizar a notificação de várias maneiras. Consulte os parâmetros de ServiceWorkerRegistration.showNotification() para saber mais.

Abrir um URL quando um usuário clicar em uma notificação

No mundo real, você provavelmente usará a notificação como uma forma de reengajar o usuário e solicitar que ele visite seu site. Para fazer isso, você precisa configurar um pouco mais o service worker.

  1. Substitua o comentário // TODO no manipulador de eventos notificationclick do service worker pelo seguinte código:

    event.notification.close();
    event.waitUntil(self.clients.openWindow('https://web.dev'));
    
  2. Volte para a guia do app, envie outra notificação para você e clique nela. O navegador vai abrir uma nova guia e carregar https://web.dev.

Próximas etapas