Até agora, abordamos a inscrição de um usuário e o envio de uma mensagem push. A próxima etapa é receber essa mensagem push no dispositivo do usuário e mostrar uma notificação (assim como fazer qualquer outro trabalho que quisermos fazer).
O evento push
Quando uma mensagem é recebida, um evento push é enviado no service worker.
O código para configurar um listener de eventos push precisa ser bastante semelhante a qualquer outro listener de eventos que você escreveria em JavaScript:
self.addEventListener('push', function(event) {
if (event.data) {
console.log('This push event has data: ', event.data.text());
} else {
console.log('This push event has no data.');
}
});
A parte mais estranha desse código para a maioria dos desenvolvedores que são iniciantes em service workers é a variável
self
. self
é usado com frequência em workers da Web, que são service workers. self
se refere ao escopo global, mais ou menos como window
em uma página da Web. No entanto, para workers da Web e service workers,
self
se refere ao worker em si.
No exemplo acima, self.addEventListener()
pode ser considerado como a adição de um listener de evento ao
próprio service worker.
No exemplo de evento push, verificamos se há dados e imprimimos algo no console.
Há outras maneiras de analisar os dados de um evento push:
// Returns string
event.data.text()
// Parses data as JSON string and returns an Object
event.data.json()
// Returns blob of data
event.data.blob()
// Returns an arrayBuffer
event.data.arrayBuffer()
A maioria das pessoas usa json()
ou text()
, dependendo do que esperam do aplicativo.
Este exemplo demonstra como adicionar um listener de evento push e como acessar dados, mas
ele não tem duas partes muito importantes da funcionalidade. Ele não mostra uma notificação e não
usa event.waitUntil()
.
Esperar até
Uma das coisas a entender sobre os service workers é que você tem pouco controle sobre quando
o código do service worker será executado. O navegador decide quando ativá-lo e quando
encerrar. A única maneira de dizer ao navegador: "Ei, estou muito ocupado fazendo coisas
importantes" é transmitindo uma promessa para o método event.waitUntil()
. Com isso, o navegador
vai manter o service worker em execução até que a promessa transmitida seja resolvida.
Com eventos push, há um requisito adicional de exibir uma notificação antes que a promessa transmitida seja resolvida.
Confira um exemplo básico de exibição de uma notificação:
self.addEventListener('push', function(event) {
const promiseChain = self.registration.showNotification('Hello, World.');
event.waitUntil(promiseChain);
});
A chamada self.registration.showNotification()
é o método que mostra uma notificação para
o usuário e retorna uma promessa que será resolvida quando a notificação for exibida.
Para manter este exemplo o mais claro possível, atribuí essa promessa a uma
variável chamada promiseChain
. Depois, ela é transmitida para event.waitUntil()
. Sei que isso é
muito detalhado, mas já vi vários problemas que culminaram em
um mal-entendido sobre o que precisa ser transmitido para waitUntil()
ou como resultado de cadeias de
promessas quebradas.
Um exemplo mais complicado com uma solicitação de rede para dados e rastreamento do evento push com análise pode ser parecido com este:
self.addEventListener('push', function(event) {
const analyticsPromise = pushReceivedTracking();
const pushInfoPromise = fetch('/api/get-more-data')
.then(function(response) {
return response.json();
})
.then(function(response) {
const title = response.data.userName + ' says...';
const message = response.data.message;
return self.registration.showNotification(title, {
body: message
});
});
const promiseChain = Promise.all([
analyticsPromise,
pushInfoPromise
]);
event.waitUntil(promiseChain);
});
Aqui, estamos chamando uma função que retorna uma promessa pushReceivedTracking()
,
que, para fins de exemplo, podemos fingir que fará uma solicitação de rede
para nosso provedor de análise. Também fazemos uma solicitação de rede, recebemos a
resposta e mostramos uma notificação usando os dados de respostas para o título e
a mensagem da notificação.
Podemos garantir que o worker do serviço seja mantido ativo enquanto essas duas tarefas são realizadas combinando
essas promessas com Promise.all()
. A promessa resultante é transmitida para event.waitUntil()
,
o que significa que o navegador vai esperar até que as duas promessas sejam concluídas antes de verificar se uma notificação
foi mostrada e encerrar o service worker.
O motivo pelo qual precisamos nos preocupar com waitUntil()
e como usá-lo é que um dos problemas mais comuns que os desenvolvedores enfrentam é que, quando a cadeia de promessas está incorreta ou quebrada, o Chrome mostra esta notificação "padrão":
O Chrome só vai mostrar a notificação "Este site foi atualizado em segundo plano" quando uma
mensagem push for recebida e o evento push no worker do serviço não mostrar uma
notificação depois que a promessa transmitida para event.waitUntil()
for concluída.
O principal motivo pelo qual os desenvolvedores são pegos é que o código
muitas vezes chama self.registration.showNotification()
, mas não faz
nada com a promessa que ele retorna. Isso faz com que a notificação padrão
seja mostrada de forma intermitente. Por exemplo, poderíamos remover o retorno de
self.registration.showNotification()
no exemplo acima e correr o risco de ver esta
notificação.
self.addEventListener('push', function(event) {
const analyticsPromise = pushReceivedTracking();
const pushInfoPromise = fetch('/api/get-more-data')
.then(function(response) {
return response.json();
})
.then(function(response) {
const title = response.data.userName + ' says...';
const message = response.data.message;
self.registration.showNotification(title, {
body: message
});
});
const promiseChain = Promise.all([
analyticsPromise,
pushInfoPromise
]);
event.waitUntil(promiseChain);
});
É fácil perder isso de vista.
Se você receber essa notificação, verifique as cadeias de promessas e event.waitUntil()
.
Na próxima seção, vamos analisar o que podemos fazer para estilizar notificações e o conteúdo que podemos exibir.
A seguir
- Visão geral das notificações push na Web
- Como o push funciona
- Assinar um usuário
- UX de permissão
- Como enviar mensagens com bibliotecas push da Web
- Protocolo push da Web
- Como lidar com eventos push
- Como mostrar uma notificação
- Comportamento da notificação
- Padrões de notificação comuns
- Perguntas frequentes sobre notificações push
- Problemas comuns e como informar bugs