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 fazendo e não fala muito sobre conceitos. Confira Como funcionam as notificações push? para saber mais sobre os conceitos de notificações push.

O código do servidor deste codelab já foi concluído. Você só vai implementar o cliente neste codelab. Para saber como implementar um servidor de notificação push, consulte Codelab: criar um servidor de notificação push.

Confira push-notifications-client-codelab-complete (fonte) para conferir o código completo.

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

Receber uma cópia editável do código

O editor de código à direita dessas instruções será chamado de Glitch UI ao longo deste codelab.

  1. Clique em Remix to Edit para tornar o projeto editável.

Configurar a autenticação

Antes de fazer as notificações por push funcionarem, você precisa configurar o servidor e o cliente com chaves de autenticação. Consulte Assinar suas solicitações de protocolo push da Web para saber o motivo.

  1. Na interface do Glitch, clique em Tools e em Terminal para abrir o terminal do Glitch.
  2. No terminal do Glitch, execute npx web-push generate-vapid-keys. Copie os valores da chave privada e da chave pública.
  3. Na interface do Glitch, abra .env e atualize VAPID_PUBLIC_KEY e VAPID_PRIVATE_KEY. Defina VAPID_SUBJECT como mailto:test@test.test. Todos esses valores precisam estar entre aspas duplas. Depois de fazer as atualizações, o arquivo .env vai ficar parecido com este:
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Feche o terminal do Glitch.
  1. Abra public/index.js.
  2. Substitua VAPID_PUBLIC_KEY_VALUE_HERE pelo valor da chave pública.

Registrar um service worker

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

  1. Substitua o comentário // TODO add startup logic here pelo seguinte código:
// TODO add startup logic here
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);
  1. Para visualizar o site, pressione View App. Em seguida, pressione Fullscreen tela cheia.
  1. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir as Ferramentas do desenvolvedor.
  2. Clique na guia Console. A mensagem Service worker was registered. vai aparecer registrada no console.

Solicitar permissão de notificação push

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

  1. Na interface do Glitch, clique em View Source para voltar ao código.
  2. Em public/index.js, substitua o comentário // TODO em subscribeButtonHandler() pelo seguinte código:
// TODO
// 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.');
}
  1. Volte para a guia do app e clique em Assinar para receber notificações push. Seu navegador ou sistema operacional provavelmente vai perguntar se você quer permitir que o site envie notificações push. Clique em Permitir (ou em qualquer frase equivalente usada pelo navegador/SO). No console, você vai encontrar uma mensagem indicando se a solicitação foi aceita ou negada.

Inscrever-se para receber notificações push

O processo de assinatura envolve a interação com um serviço da Web controlado pelo fornecedor do navegador, que é chamado de serviço push. Depois de receber as informações de assinatura de notificação push, você precisa enviá-las a um servidor e fazer com que ele as armazene em um banco de dados por um longo período. Consulte Inscrever o cliente para receber notificações push para mais contexto sobre o processo de assinatura.

  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. Talvez um dia seja possível enviar mensagens por push sem mostrar notificações visíveis ao usuário (push silencioso), mas os navegadores atualmente não permitem esse recurso por motivos 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 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.

  1. Substitua o comentário // TODO em unsubscribeButtonHandler() pelo seguinte código:
// TODO
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 exibi-la como uma notificação

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

  1. Abra public/service-worker.js e substitua o comentário // TODO no manipulador de eventos push do worker do serviço pelo seguinte código:
// TODO
let data = event.data.json();
const image = 'https://cdn.glitch.com/614286c9-b4fc-4303-a6a9-a4cef0601b74%2Flogo.png?v=1605150951230';
const options = {
  body: data.options.body,
  icon: image
}
self.registration.showNotification(
  data.title, 
  options
);
  1. Volte para a guia do app.
  2. Clique em Notificar. Você vai receber uma notificação push.
  3. Tente abrir o URL da guia do app em outros navegadores (ou até em outros dispositivos), passando pelo fluxo de trabalho de assinatura e clicando em Notificar todos. Você vai receber a mesma notificação push em todos os navegadores em que se inscreveu. Consulte Compatibilidade com navegadores para conferir uma lista de combinações de navegador/SO que funcionam ou não.

É 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 clica em uma notificação

Na prática, você provavelmente vai usar a notificação como uma forma de reativar o usuário e pedir que ele acesse seu site. Para isso, você precisa configurar o worker de serviço um pouco mais.

  1. Substitua o comentário // TODO no manipulador de eventos notificationclick do worker de serviço pelo seguinte código:
// TODO
event.notification.close();
event.waitUntil(self.clients.openWindow('https://web.dev'));
  1. Volte para a guia do app, envie outra notificação para você mesmo e clique nela. O navegador vai abrir uma nova guia e carregar https://web.dev.

Próximas etapas