Eventos push

Até agora, abordamos a inscrição de um usuário e o envio de uma mensagem push. A próxima etapa é recebe essa mensagem push no dispositivo do usuário e exibe uma notificação (assim como qualquer outro trabalho que talvez queiramos fazer).

O evento de push

Quando uma mensagem é recebida, um evento de push é despachado no seu service worker.

O código para configurar um listener de eventos de push deve ser bastante semelhante ao de qualquer outro evento 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 novos nos service workers é o self. variável. self é comumente usado em Web Workers, que são um service worker. self refere-se a escopo global, como window em uma página da Web. Já para web workers e service workers, self refere-se ao próprio worker.

No exemplo acima, self.addEventListener() pode ser considerado como a adição de um listener de eventos o próprio service worker.

No exemplo do evento push, verificamos se há algum dado e imprimimos algo no console.

Há outras maneiras de analisar dados de um evento de 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 eventos push e como acessar dados, mas é faltam duas funções muito importantes. Ele não está exibindo uma notificação não usar event.waitUntil().

Esperar até

Uma das coisas que você precisa entender sobre 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 encerrá-la. A única maneira de dizer ao navegador: "Ei, estou muito ocupado fazendo importante coisas", é transmitir uma promessa para o método event.waitUntil(). Com isso, o navegador manter o service worker em execução até que a promessa que você transmitiu seja resolvida.

Com os eventos push, há um requisito adicional de que você precise exibir uma notificação antes a promessa que você transmitiu se estabeleceu.

Este é um exemplo básico de como mostrar uma notificação:

self.addEventListener('push', function(event) {
    const promiseChain = self.registration.showNotification('Hello, World.');

    event.waitUntil(promiseChain);
});

Chamar 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 esse exemplo o mais claro possível, atribuí essa promessa a uma chamada promiseChain. Ele é transmitido para event.waitUntil(). Eu sei que é muito detalhado, mas já vi uma série de problemas que culminaram como resultado de Entendendo mal o que precisa ser transmitido para waitUntil() ou como resultado de uma promessa quebrada. cadeias de caracteres.

Um exemplo mais complicado com uma solicitação de rede para dados e o acompanhamento de um evento push com o Google Analytics pode ficar assim:

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 este exemplo, podemos fingir que fará uma solicitação de rede ao nosso provedor de análises. Também estamos fazendo uma solicitação de rede, obtendo o de resposta e mostrando uma notificação usando os dados de respostas para o título e da notificação.

Podemos garantir que o service worker continue ativo enquanto ambas as tarefas são feitas combinando essas promessas com Promise.all(). A promessa resultante é transmitida para event.waitUntil(). o que significa que o navegador esperará até que as duas promessas sejam concluídas antes de verificar se uma notificação foi exibido e encerrando o service worker.

Devemos nos preocupar com o waitUntil() e como usá-lo porque um dos problemas comuns que os desenvolvedores enfrentam é que, quando a cadeia de promessas estiver incorreta / corrompida, o Chrome mostrar "padrão" notificação:

Uma imagem da notificação padrão no Chrome

O Chrome só vai mostrar a mensagem "Este site foi atualizado em segundo plano". quando um for recebida e o evento de push no service worker não mostrar um notificação depois que a promessa transmitida para event.waitUntil() for concluída.

A principal razão pela qual os desenvolvedores são pegos por isso é que seu código muitas vezes chamam self.registration.showNotification(), mas não fazem isso qualquer coisa com a promessa que ela retorna. Isso resulta na notificação padrão de forma intermitente em exibição. Por exemplo, poderíamos remover o retorno para self.registration.showNotification() no exemplo acima, e corremos o risco de ver isso 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);
});

Dá para ver que é fácil não perceber.

Lembre-se: caso essa notificação seja exibida, verifique suas cadeias de promessas e o event.waitUntil().

Na próxima seção, veremos o que podemos fazer para definir o estilo das notificações e qual conteúdo podemos exibir.

A seguir

Code labs