Codelab: criar um cliente de notificação push

Kate jeffreys
Kate Jeffreys
Kayce Bascos
Kayce Basques

Este codelab mostra detalhadamente como criar um cliente de notificação 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.

O foco deste codelab é ajudar você a aprender fazendo, e não fala muito sobre conceitos. Confira Como as notificações push funcionam? para saber mais sobre os conceitos dessa notificação.

O código do servidor deste codelab já foi concluído. 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, Firefox
  • Android: Chrome, Firefox

Sabe-se que este codelab não funciona com os sistemas operacionais a seguir (ou combinações de sistema operacional e navegador):

  • macOS: Brave, Edge e Safari
  • iOS

Instalação

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

O editor de código que você vê à direita destas instruções será chamado de interface 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, configure 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 Glitch.
  2. No terminal 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 de falha.
  1. Abra o public/index.js.
  2. Substitua VAPID_PUBLIC_KEY_VALUE_HERE pelo valor da sua 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 Ver app. Em seguida, pressione Tela cheia 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 no carregamento da página. Em vez disso, a interface precisa perguntar ao usuário se ele quer receber notificações push. Depois da confirmação explícita (com um clique de botão, por exemplo), você pode 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 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 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 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 serviço de push. Depois de receber as informações de assinatura da notificação push, você precisa enviá-las a um servidor e fazer com que o servidor as armazene em um banco de dados de longo prazo. Consulte Inscrever o cliente nas notificações push para mais contexto sobre o processo de assinatura.

  1. Adicione o código destacado a seguir 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. Um dia pode ser possível enviar mensagens sem exibir notificações visíveis ao usuário (envios silenciosos), mas os navegadores atualmente 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 ele 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 que foram enviadas ao cliente pelo 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é mesmo em outros dispositivos, siga o fluxo de trabalho da assinatura e clique em Notificar tudo. Você receberá a mesma notificação push em todos os navegadores que assinou. Consulte a página Compatibilidade do navegador para conferir uma lista de combinações de navegador/SO que funcionam ou não.

Você pode 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

No mundo real, você provavelmente usará a notificação como uma maneira de reengajar o usuário e direcioná-lo para seu site. Para fazer isso, você precisa configurar o service worker um pouco mais.

  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 para você mesmo e clique na notificação. Uma nova guia será aberta e o navegador carregará https://web.dev.

Próximas etapas