Codelab: criar um cliente de notificação push

Kate Jeffreys
Kate Jeffreys
Kayce Basques
Kayce Basques

Este codelab mostra em etapas como criar um cliente de notificações push. Ao final do codelab, você terá um cliente que:

  • Inscreve o usuário nas 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ção push.

O código do servidor deste codelab já está completo. Você só vai implementar o cliente neste codelab. Para aprender a implementar um servidor de notificações push, consulte Codelab: criar um servidor de notificações push.

Confira push-notifications-client-codelab-complete (fonte) para ver 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 e 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 e Safari
  • iOS

Configuração

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

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

  1. Clique em Remixar para editar para tornar o projeto editável.

Configurar a autenticação

Para que as notificações push funcionem, é preciso configurar o servidor e o cliente com chaves de autenticação. Consulte Assinar suas solicitações de protocolo de push da Web para saber o motivo.

  1. Na interface do Glitch, clique em Tools e em Terminal para abrir o terminal.
  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 devem ser colocados entre aspas duplas. Depois de fazer as atualizações, o arquivo .env ficará semelhante a este:
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Feche o terminal do Glitch.
  1. Abra o public/index.js.
  2. Substitua VAPID_PUBLIC_KEY_VALUE_HERE pelo valor da chave pública.

Registrar um service worker

Em algum momento, seu cliente precisará de um service worker para receber e exibir notificações. É melhor registrar o service worker o quanto antes. Consulte Receber e exibir as mensagens enviadas como notificações para mais contexto.

  1. Substitua o comentário // TODO add startup logic here por este 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 modo tela cheia.
  1. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir o DevTools.
  2. Clique na guia Console. Você verá a mensagem Service worker was registered. registrada no console.

Solicitar permissão de notificações push

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

  1. Na interface do Glitch, clique em Ver código-fonte para retornar 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 aplicativo e clique em Inscrever-se para push. Seu navegador ou sistema operacional provavelmente perguntará se você quer permitir que o site envie notificações push. Clique em Permitir (ou qualquer frase equivalente que seu navegador/SO use). No console, você verá uma mensagem indicando se a solicitação foi aceita ou negada.

Inscrever-se nas notificações push

O processo de assinatura 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 da assinatura da notificação push, você precisa enviá-las a um servidor e armazená-las em um banco de dados a longo prazo. 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 sem mostrar notificações visíveis ao usuário (envios silenciosos), mas os navegadores não permitem esse recurso por 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 seu 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, a 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 notificação

Como mencionado anteriormente, você precisa de um service worker para lidar com 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:
// 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 Receber notificação. Você vai receber uma notificação push.
  3. Tente abrir o URL da guia do app em outros navegadores (ou até em outros dispositivos), seguindo o fluxo de trabalho da assinatura e clicando em Notificar tudo. Você receberá a mesma notificação push em todos os navegadores em que se inscreveu. Consulte Compatibilidade do navegador novamente para ver uma lista de combinações de navegador/SO que funcionam ou não.

Você pode personalizar a notificação de várias maneiras. Veja 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 levá-lo a visitar 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:
// TODO
event.notification.close();
event.waitUntil(self.clients.openWindow('https://web.dev'));
  1. Volte para a guia do app, envie outra notificação e clique nela. Seu navegador abrirá uma nova guia e carregará https://web.dev.

Próximas etapas