Back

Implementando Notificações Push com a Web Push API

Implementando Notificações Push com a Web Push API

As notificações push mantêm os usuários engajados mesmo quando não estão usando ativamente sua aplicação web. A Web Push API permite enviar atualizações oportunas diretamente para os dispositivos dos usuários sem depender de serviços de terceiros. Este guia mostra como implementar notificações nativas usando Service Workers, autenticação VAPID e criptografia adequada.

Pontos-Chave

  • A Web Push API permite notificações push nativas sem serviços de terceiros
  • Service Workers e autenticação VAPID são componentes essenciais
  • Conexão HTTPS é obrigatória para implementação
  • Diferentes navegadores têm requisitos variados para notificações push

Pré-requisitos e Suporte dos Navegadores

Antes de implementar notificações push, certifique-se de que sua aplicação atende a estes requisitos:

  • Conexão HTTPS (necessária para Service Workers)
  • Suporte de navegadores modernos (Chrome, Firefox, Edge, Safari 16.4+)
  • Compatibilidade com Service Worker
// Feature detection
if ('serviceWorker' in navigator && 'PushManager' in window) {
  // Push notifications supported
}

Registrando um Service Worker

O Service Worker atua como um proxy entre sua aplicação web e os serviços push. Registre-o durante o carregamento da página:

navigator.serviceWorker.register('/sw.js')
  .then(registration => {
    console.log('Service Worker registered:', registration);
  })
  .catch(error => {
    console.error('Registration failed:', error);
  });

Configurando Chaves VAPID

VAPID (Voluntary Application Server Identification) autentica seu servidor com os serviços push. Gere um par de chaves uma vez para sua aplicação:

# Using web-push library (Node.js)
npm install web-push
npx web-push generate-vapid-keys

Armazene a chave privada de forma segura em seu servidor e use a chave pública na assinatura do lado do cliente.

Criando Assinaturas Push

Solicite permissão e inscreva os usuários para receber notificações push:

async function subscribeToPush() {
  const registration = await navigator.serviceWorker.ready;
  
  // Request permission (only on user gesture)
  const permission = await Notification.requestPermission();
  if (permission !== 'granted') return;
  
  // Subscribe with VAPID public key
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
  });
  
  // Send subscription to your server
  await fetch('/api/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(subscription)
  });
}

// Helper function to convert base64 to Uint8Array
function urlBase64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  const base64 = (base64String + padding)
    .replace(/\-/g, '+')
    .replace(/_/g, '/');
  
  const rawData = window.atob(base64);
  const outputArray = new Uint8Array(rawData.length);
  
  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }
  return outputArray;
}

O objeto de assinatura contém:

  • Endpoint: URL única para envio de mensagens
  • Keys: Chaves de criptografia (p256dh e auth) para segurança do payload

Implementação no Lado do Servidor

Seu servidor deve criptografar mensagens e enviá-las para o endpoint do serviço push. Usar a biblioteca web-push simplifica isso:

const webpush = require('web-push');

webpush.setVapidDetails(
  'mailto:your-email@example.com',
  VAPID_PUBLIC_KEY,
  VAPID_PRIVATE_KEY
);

// Send notification
const payload = JSON.stringify({
  title: 'New Message',
  body: 'You have a new update',
  icon: '/icon-192.png',
  url: 'https://example.com/updates'
});

webpush.sendNotification(subscription, payload, {
  TTL: 86400, // 24 hours
  urgency: 'high'
})
  .catch(error => {
    console.error('Error sending notification:', error);
  });

Manipulando Eventos Push no Service Worker

O Service Worker recebe e exibe notificações push:

// sw.js
self.addEventListener('push', event => {
  const data = event.data?.json() || {};
  
  const options = {
    body: data.body || 'Default message',
    icon: data.icon || '/icon.png',
    badge: '/badge.png',
    vibrate: [200, 100, 200],
    data: { url: data.url }
  };
  
  event.waitUntil(
    self.registration.showNotification(data.title || 'Notification', options)
  );
});

// Handle notification clicks
self.addEventListener('notificationclick', event => {
  event.notification.close();
  
  event.waitUntil(
    clients.openWindow(event.notification.data?.url || '/')
  );
});

Requisitos Específicos dos Navegadores

Diferentes navegadores impõem requisitos variados para a implementação da Web Push API:

  • Chrome/Edge: Exigem notificações visíveis para cada mensagem push
  • Firefox: Permite push silencioso limitado com sistema de cota
  • Safari: Requer notificações visíveis e não suporta push silencioso

Observação: Os tamanhos de payload são limitados: Chrome/Edge/Firefox suportam até 4KB, enquanto o Safari suporta 2KB. Mantenha as mensagens leves e busque dados adicionais na aplicação, se necessário.

Sempre exiba notificações imediatamente ao receber eventos push para manter as permissões em todos os navegadores.

Melhores Práticas de Segurança

Proteja sua implementação de notificações push:

  1. Endpoints seguros: Nunca exponha endpoints de assinatura publicamente
  2. Criptografe payloads: Todos os dados de mensagem devem usar criptografia ECDH
  3. Proteja chaves VAPID: Armazene-as com segurança e regenere apenas se comprometidas
  4. Implemente proteção CSRF: Valide solicitações de assinatura
  5. Limitação de taxa: Previna abusos com throttling no lado do servidor

Gerenciando o Ciclo de Vida da Assinatura

Lide com mudanças e expiração de assinatura:

// In Service Worker
self.addEventListener('pushsubscriptionchange', event => {
  event.waitUntil(
    self.registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
    })
      .then(subscription => {
        // Update server with new subscription
        return fetch('/api/update-subscription', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(subscription)
        });
      })
  );
});

Conclusão

A Web Push API fornece uma abordagem baseada em padrões para implementar notificações push sem dependência de fornecedores. Ao combinar Service Workers, autenticação VAPID e criptografia adequada, você pode entregar notificações oportunas que funcionam em navegadores modernos. Lembre-se de respeitar as preferências dos usuários, lidar com eventos do ciclo de vida da assinatura e seguir requisitos específicos da plataforma para uma implementação robusta.

Comece com entrega básica de notificações e depois adicione recursos como botões de ação, anexos de imagem e agrupamento de notificações conforme sua implementação amadurece.

Perguntas Frequentes

Não, as notificações push requerem uma conexão ativa com a internet para receber mensagens do serviço push. No entanto, Service Workers podem armazenar notificações em cache e exibi-las quando a conectividade retornar.

Quando a permissão é negada, você não pode enviar notificações push para esse usuário. Você deve aguardar que ele altere manualmente as permissões nas configurações do navegador. Considere implementar métodos alternativos de engajamento, como notificações dentro da aplicação.

A maioria dos serviços push limita o tamanho do payload a 4KB. Chrome e Firefox suportam até 4KB, enquanto o Safari suporta até 2KB. Mantenha os payloads mínimos e busque dados adicionais quando a notificação for recebida, se necessário.

Sim, notificações push podem ser recebidas quando o navegador está fechado na maioria das plataformas. No entanto, isso depende do sistema operacional e do navegador. Navegadores móveis podem ter restrições baseadas em configurações de otimização de bateria.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay