Usar um service worker para gerenciar notificações

Kate Jeffreys
Kate Jeffreys

Neste codelab, você vai usar um service worker para gerenciar notificações. As instruções aqui pressupõem que você já esteja familiarizado com service workers e as noções básicas sobre como solicitar permissões e enviar notificações. Se você precisar se lembrar de notificações, consulte a Começar a usar a API Notifications o codelab. Para saber mais sobre service workers, consulte Introdução aos service workers de Matt Gaunt.

Remixar o app de exemplo e visualizá-lo em uma nova guia

As notificações são bloqueadas automaticamente no app Glitch incorporado, então não é possível visualizar o app nesta página. Em vez disso, faça o seguinte:

  1. Clique em Remixar para editar para tornar o projeto editável.
  2. Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia tela cheia

O Glitch será aberto em uma nova guia do Chrome.

Durante este codelab, faça mudanças no código no Glitch incorporado nesta página. Atualize a nova guia com o app ativo para conferir as mudanças.

Conhecer o app de exemplo e o código inicial

Comece conferindo o aplicativo publicado na nova guia do Chrome:

  1. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir o DevTools.
  2. Clique na guia Console.

  3. Verifique se a opção Informações está selecionada no menu suspenso Níveis. ao lado da caixa Filtro.

  4. No console do DevTools do app ativo, você vai receber uma mensagem do console:

    TODO: Implement getRegistration().

    Essa é uma mensagem de um stub de função que você vai implementar neste codelab.

Agora, vamos conferir o código do app de exemplo no Glitch incorporado nesta página.

  1. No Glitch incorporado, confira public/index.js:

    • Há quatro stubs para as funções que você implementará: registerServiceWorker, getRegistration, unRegisterServiceWorker e sendNotification.

    • A função requestPermission solicita a permissão do usuário para enviar notificações. Se você fez o codelab Introdução à API Notifications, a função requestPermission é usada aqui. A única diferença é que agora ele também atualiza a interface do usuário depois de resolver a solicitação de permissão.

    • A função updateUI atualiza todos os botões e mensagens do app.

    • A função initializePage realiza a detecção de recursos para a capacidade do service worker no navegador e atualiza a interface do usuário do app.

    • O script aguarda até que a página seja carregada e a inicializa.

  2. No Glitch incorporado, abra public/service-worker.js.

    Como o nome sugere, você vai adicionar código ao app para registrar esse arquivo como service worker.

    Embora o arquivo ainda não esteja sendo usado pelo app, ele contém um código inicial que vai mostrar uma mensagem no console quando o service worker for ativado.

    Você vai adicionar um código ao public/service-worker.js para processar as notificações quando elas forem recebidas pelo service worker.

Registrar o service worker

Nesta etapa, você vai escrever um código que executa quando o usuário clicar em Registrar service worker na interface do app. Esse código vai registrar public/service-worker.js como um service worker.

  1. No editor do Glitch incorporado, abra public/index.js. Substitua a função registerServiceWorker por este código:

    // Use the Service Worker API to register a service worker.
    async function registerServiceWorker() {
      await navigator.serviceWorker.register('./service-worker.js')
      updateUI();
    }
    

    O registerServiceWorker usa a declaração async function para tornar o processamento de promessas mais conveniente. Isso permite await o valor resolvido de uma Promise. Por exemplo, a função acima aguarda o resultado do registro de um service worker antes de atualizar a interface. Consulte await no MDN para mais informações.

  2. Agora que o usuário pode registrar um service worker, você pode receber uma referência para o objeto de registro do service worker. Em public/index.js, substitua a função getRegistration pelo seguinte código:

    // Get the current service worker registration.
    function getRegistration() {
      return navigator.serviceWorker.getRegistration();
    }
    

    A função acima usa API Service Worker para obter o registro atual do service worker, se houver. Isso torna a obtenção de uma referência ao registro do service worker um pouco mais conveniente.

  • Para concluir a funcionalidade de registro do service worker, adicione o código para cancelar o registro do service worker. Substitua a função unRegisterServiceWorker por este código:

    // Unregister a service worker, then update the UI.
    async function unRegisterServiceWorker() {
      // Get a reference to the service worker registration.
      let registration = await getRegistration();
      // Await the outcome of the unregistration attempt
      // so that the UI update is not superceded by a
      // returning Promise.
      await registration.unregister();
      updateUI();
    }
    

Na guia em que você está visualizando o app publicado, atualize a página. Os botões Registrar service worker e Cancelar registro de service worker agora devem estar funcionando.

Enviar notificações para o service worker

Nesta etapa, você vai criar um código que será executado quando o usuário clicar em Enviar uma notificação na interface do app. Esse código vai criar uma notificação, verificar se um service worker está registrado e enviar a notificação para o service worker usando o método postMessage.

No editor do Glitch incorporado, abra public/index.js e substitua a função sendNotification pelo seguinte código:

// Create and send a test notification to the service worker.
async function sendNotification() {
  // Use a random number as part of the notification data
  // (so you can tell the notifications apart during testing!)
  let randy = Math.floor(Math.random() * 100);
  let notification = {
    title: 'Test ' + randy,
    options: { body: 'Test body ' + randy }
  };
  // Get a reference to the service worker registration.
  let registration = await getRegistration();
  // Check that the service worker registration exists.
  if (registration) {
    // Check that a service worker controller exists before
    // trying to access the postMessage method.
    if (navigator.serviceWorker.controller) {
      navigator.serviceWorker.controller.postMessage(notification);
    } else {
      console.log('No service worker controller found. Try a soft reload.');
    }
  }
}

Confira o que esse código faz:

  • sendNotification é uma função assíncrona, então você pode usar await para ter uma referência ao registro do service worker.

  • O método postMessage do service worker envia dados do app para o service worker. Consulte a documentação do MDN sobre postMessage para saber mais.

  • O código verifica a presença da propriedade navigator.serviceWorker.controller antes de tentar acessar a função postMessage. navigator.serviceWorker.controller será null se não houver service workers ativos ou se a página tiver sido atualizada à força (Shift+Atualizar). Consulte a documentação do controlador ServiceWorker no MDN para mais informações.

Processar notificações no service worker

Nesta etapa, você vai escrever um código no service worker que processará as mensagens postadas nele e exibirá notificações para o usuário.

No editor do Glitch incorporado, abra public/service-worker.js. Adicione o seguinte código ao final do arquivo:

// Show notification when received
self.addEventListener('message', (event) => {
  let notification = event.data;
  self.registration.showNotification(
    notification.title,
    notification.options
  ).catch((error) => {
    console.log(error);
  });
});

Veja uma explicação rápida:

  • self é uma referência ao próprio service worker.

  • Embora o service worker agora gerencie a exibição de notificações, a interface principal do app ainda é responsável por receber a permissão de notificações do usuário. Se a permissão não for concedida, a promessa retornada por showNotification será rejeitada. O código acima usa um bloco catch para evitar um erro de rejeição de Promise não detectado e lidar com esse erro de forma um pouco mais simples.

Se tiver dificuldades, consulte glitch.com/edit/#!/codelab-notifications-service-worker-completed para ver o código concluído.

Acesse o próximo codelab desta série: Criar um servidor de notificações push.