Entre para a LISTA VIP da Black Friday

00

DIAS

00

HORAS

00

MIN

00

SEG

Clique para saber mais
Alura > Cursos de Front-end > Cursos de React > Conteúdos de React > Primeiras aulas do curso React: implemente notificações push e sincronização em background

React: implemente notificações push e sincronização em background

Notificações Push - Apresentação

Você já se perguntou como são implementadas as notificações que aparecem em um website quando está navegando, por exemplo, na Amazon ou no próprio site da Netshoes? Se não sabe, fique conosco que vamos te explicar tudo.

Audiodescrição: Neilton Seguins se identifica como um homem negro de pele clara. Tem cabelos curtos, escuros e encaracolados e olhos castanho-escuros. Usa óculos com armação retangular e uma camiseta laranja-clara. Ao fundo, parede lisa sem decorações com iluminação gradiente do rosa ao azul.

Neilton Seguins vai te acompanhar nesse curso, onde vamos aprender como implementar notificações push em nossas aplicações, as PWAs (Progressive Web App).

O que vamos aprender?

Trabalharemos com a aplicação do Jornada Milhas, a qual já tem algumas funcionalidades de uma PWA, como, por exemplo, a possibilidade de instalação.

Na barra de endereços, podemos clicar na opção de "Instalar Jornada Milhas" ao lado do ícone de favoritar. Caso a aplicação ainda não esteja instalada, será solicitada a instalação. Como já temos ela instalada, podemos apenas clicar em "Abrir".

Desse modo, abrimos a aplicação do Jornada Milhas em uma nova janela separada, porque já está instalada na máquina. Com isso, podemos navegar pelos pacotes de viagens disponíveis.

Se clicamos no botão "Ver detalhes" de um pacote promocional, por exemplo, da visita à Cordilheira dos Andes, seremos redirecionados para uma nova tela, onde podemos concluir a reserva.

Nosso objetivo é implementar notificações push na aplicação, para conseguir manter o engajamento da pessoa usuária com o site.

A partir daí, vamos conhecer o que é a API Notification e entender como trabalhar com o Firebase Cloud Message (FCM), que é onde vamos criar as campanhas de notificação para as pessoas usuárias.

Além disso, aprenderemos como implementar notificações customizadas, uma biblioteca chamada React Toastify, e muito mais.

Pré-requisitos

E o que precisa saber para continuar neste curso? Recomendamos que já tenha uma boa base de React com JavaScript - inclusive uma boa base de JavaScript é mais que suficiente para continuar nesse curso.

Tem muita conteúdo interessante para aprender durante esse curso. Vamos começar?

Notificações Push - Solicitando permissão do usuário

Quando você está no seu celular e recebe uma notificação do Instagram de alguém que curtiu uma publicação sua, você clica na notificação, vai para o aplicativo e, depois de verificar a curtida, continua no Instagram.

Isso é uma estratégia muito comum de engajamento que os serviços utilizam para manter você na aplicação.

Como estamos transformando a aplicação Jornada Milhas em uma PWA, vamos implementar essa funcionalidade de notificações push.

Solicitando permissão

No Visual Studio Code, vamos criar uma nova pasta dentro de "src", chamada "hooks". Em seguida, criaremos um arquivo chamado useNotification.jsx para a criação de um hook customizado do React.

A estrutura de um hook é bem parecida com a de um componente. Usaremos a sigla rafce para criar a estrutura do React Arrow Function Export Component automaticamente:

useNotification.jsx:

import React from "react";

const useNotification = () => {
    return (
        <div>useNotification</div>
    )
}

export default useNotification;

Porém, criamos uma const useNotification que vai retornar inicialmente um objeto vazio, ao invés de um JSX como acontece no componente. Para isso, basta abrir e fechar chaves depois de return.

Além disso, podemos excluir a importação do React no topo do arquivo.

const useNotification = () => {
    return {}
}

export default useNotification;

Dentro desse useNotification é onde implementaremos a funcionalidade de notificação.

O primeiro passo para enviar notificações para pessoas usuárias é perguntar se aceitam receber as notificações. Utilizamos uma API da web, chamada API Notification, para solicitar essa permissão.

Dentro do hook useNotification, vamos criar uma constante chamada requestNotificationPermission, que vai receber uma arrow function assíncrona.

Dentro da função de seta, vamos criar outra constante chamada permission, que vai receber um await da função Notification.requestPermission(). Desse modo, solicitamos a pessoa usuária que permita o envio notificações.

Em seguida, vamos fazer uma verificação com a condicional if. Entre parênteses, vamos escrever a condição permission !== "granted". Note que ao digitar as aspas, o VS Code nos dá 3 opções de permissões:

No nosso caso, vamos perguntar se a permissão foi diferente da string granted. Caso essa condição seja verdadeira, vamos, dentro do if, dar um alert() na tela da nossa aplicação, informando "Permissão não concedida".

Depois de criar a função requestNotificationPermission, vamos chamá-la dentro do useEffect, adicionando um efeito colateral na aplicação React.

Para isso, ainda dentro de useNotification, digitaremos useEffect() e passaremos uma arrow function, onde chamaremos a função requestNotificationPermission().

import { useEffect } from "react";

const useNotification = () => {
  const requestNotificationPermission = async () => {
    const permission = await Notification.requestPermission();

    if (permission !== "granted") {
      alert("Permissão não concedida");
    }
  };

  useEffect(() => {
    requestNotificationPermission();
  });

  return {};
};

export default useNotification;

Concluímos a construção do hook customizado chamado useNotification. Para usá-lo, precisamos entrar no arquivo app.jsx e chamar esse hook que, por enquanto, não retorna nada.

No app.jsx, dentro do componente App, vamos digitar const seguido de abre e fecha chaves que será igual à chamada do hook useNotification(). Também devemos importá-lo desde a pasta ./hooks/useNotification.

app.jsx:

import useNotification from "./hooks/useNotification";

function App() {
  const {} = useNotification()
  return (
    <>
      <Header />
      <Outlet />
      <Footer />
    </>
  );
}

Após salvar os arquivos, vamos voltar na aplicação do Jornada Milhas que já está rodando.

No navegador, aparece uma janela de alerta na barra de endereços, avisando que o localhost quer mostrar notificações. Nesse caso, podemos escolher entre dois botões: permitir e bloquear.

Se recarregamos a página, automaticamente aparece o aviso "notificações bloqueadas" no canto esquerdo da barra de endereços. Ao clicar nesse pop-up, podemos apertar o botão "Permitir para este site". Com isso, as notificações são permitidas nessa página.

Podemos clicar no ícone de exclamação também na barra de endereços para verificar as informações do site.

Desse modo, sabemos que aceitamos receber notificações, já que o toggle de "notificações" está ativo, mas podemos clicar no botão de "Redefinir permissão" para que as permissões sejam zeradas. Assim, ao recarregar a página, será novamente solicitado se queremos receber notificações para esse site.

Próximos passos

Concluímos a primeira etapa de solicitação de permissão para enviar notificações para a pessoa usuária.

A próxima etapa é o envio da notificação, mas antes disso precisamos criar um componente que vai servir para lançar uma notificação na tela quando haja um clique. Faremos isso na sequência.

Notificações Push - Criando o NotificationButton

Criamos a funcionalidade de solicitar a permissão da pessoa usuária para receber notificações.

Observe que, na aplicação do Jornada Milhas, no navegador, se não ativamos o toggle de permissão de notificação ou se simplesmente fechamos a janela pop-up, as notificações serão bloqueadas automaticamente.

Essa é a opção padrão, a aplicação não sabe se aceitamos ou não. É possível clicar no botão "Redefinir permissão" e recarregar a página, para pedir permissão novamente.

Você também pode clicar no ícone de exclamação na barra de endereços e selecionar "Configurações do site". Na página de "Privacidade e segurança" do navegador, você pode buscar pela opção de "Configurações do site > Notificações".

O navegador informa que o comportamento padrão, nesse caso, é abrir todas as solicitações, mas também é possível fazer outras configurações. A opção de "Abrir todas as solicitações", é justamente o comportamento de sempre perguntar se queremos receber ou não uma notificação quando recarregamos a página.

No entanto, é incômodo que essa janela pop-up apareça sempre. Uma pessoa pode simplesmente clicar em "Bloquear", porque não gosta de receber esse tipo de aviso distrativo. É por isso que, geralmente, desenvolvemos um espaço dentro da aplicação que abre essa janela mediante a um clique.

Para isso, precisamos criar um componente de botão. Inicialmente, vamos utilizá-lo para lançar uma notificação na tela, mas o propósito geral dele é de permitir que a pessoa usuária escolha o momento em que receberá a mensagem para aceitar ou bloquear o recebimento de notificações.

Criando o botão de notificação

Vamos voltar ao Visual Studio Code para criar um novo componente. Dentro da pasta "src > components", vamos criar uma nova pasta chamada "NotificationButton". Nela, vamos criar um arquivo index.jsx e outro arquivo style.js.

Iremos utilizar styled-components. Como nosso objetivo não é escrever código CSS, já vamos dar o código pronto para você colar no seu arquivo style.js:

style.js:

import styled from "styled-components";

export const ButtonWrapper = styled.div`
  position: fixed;
  bottom: 20px;
  left: 20px;
  z-index: 1000;
  display: flex;
  align-items: center;
`;

export const Button = styled.button`
  background-color: #6750a4;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  border: none;
  border-radius: 5px;
  padding: 10px 20px;
  cursor: pointer;
  position: relative;
  transition: width 0.3s;
  width: ${({ $expanded }) => ($expanded ? "250px" : "40px")};
  overflow: hidden;
  white-space: nowrap;
  text-align: left;
  &:hover {
    width: 250px;
  }
`;

export const Message = styled.span`
  margin-left: 10px;
  opacity: ${({ $expanded }) => ($expanded ? 1 : 0)};
  transition: opacity 0.3s;
`;

export const Interrogation = styled.p`
  display: block;
  font-size: 20px;
`;

Nesse arquivo style.js, estilizamos todos os componentes que utilizaremos nesse componente de botão.

Após salvar esse arquivo, vamos abrir o index.jsx para criar a estrutura do componente com o atalho rafce.

O nome da constante será NotificationButton. Lembre-se de também corrigir a opção de exportação, no final da página, para export default NotificationButton.

Dentro do return é onde vamos retornar a estrutura JSX do componente.

Antes disso, vamos criar um estado para o componente, pois será um botão que vai ficar no canto inferior esquerdo da tela, onde a pessoa vai passar o mouse em cima dele para abrir uma mensagem perguntando se a pessoa quer receber notificação.

Antes do return, digitamos const e, entre colchetes, expanded, setExpanded. E aí, vamos utilizar o useState para criar o estado. Após adicionar um sinal de igual, escrevemos useState(), passando o estado inicial como false. Desse modo, o botão vai estar colapsado, ou seja, fechado.

index.jsx:

import React, { useState } from "react";

const NotificationButton = () => {
    const [expanded, setExpanded] = useState(false);
    return (
    
    )
}

export default NotificationButton;

Dentro dos parênteses do return, na linha 6, vamos criar a estrutura do botão.

Primeiro, importaremos todos os componentes estilizados. Na linha 2, faremos uma importação nomeada usando import * chamado as Styled que será importado de from "./style".

Fazendo isso, podemos importar todos os componentes estilizados utilizando o Styled.AlgumaCoisa. Em return, vamos digitar o componente <Styled.ButtonWrapper></Styled.ButtonWrapper>, que irá envolver todo o botão.

Dentro dele, vamos criar um <Styled.Button></Styled.Button> e, nesse botão, é onde vamos renderizar algo de forma condicional.

import * as Styled from "./style";

const NotificationButton = () => {
    const [expanded, setExpanded] = useState(false);
    return (
        <Styled.ButtonWrapper>
            <Styled.Button>

            </Styled.Button>
        </Styled.ButtonWrapper>
    );
};

export default NotificationButton;

Dentro do botão, vamos abrir e fechar chaves para verificar se o expanded é verdadeiro.

Se ele for verdadeiro, vamos retornar, entre parênteses, o componente de <Styled.Message></Styled.Message, com uma mensagem dentro dele. Por enquanto, a mensagem será "Receber Notificação".

Esse <Styled.Message> recebe uma prop, que no caso é um expanded. Para isso, escrevemos um cifrão ($) e marcamos um expanded.

Essa forma de escrita é uma recomendação da biblioteca styled-components, onde qualquer prop do componente utilizado que for alterar o estilo do componente deve ser precedido de um cifrão.

Após $expanded, vamos digitar um sinal de igual e passar o estado expanded, entre chaves, para esse componente.

Caso o expanded seja falso, vamos renderizar outro componente estilizado, chamado de <Styled.Interrogation></Styled.Interrogation>. Esse componente será apenas uma interrogação.

Assim, será um botão que vai levantar a curiosidade da pessoa que, ao passar o mouse por cima, conseguirá visualizar a mensagem.

const NotificationButton = () => {
    const [expanded, setExpanded] = useState(false);
    return (
        <Styled.ButtonWrapper>
            <Styled.Button>
                {expanded ? (
                    <Styled.Message $expanded={expanded}>
                        Receber Notificação
                    </Styled.Message>
                ) : (
                    <Styled.Interrogation>?</Styled.Interrogation>
                )}
            </Styled.Button>
        </Styled.ButtonWrapper>
    );
};

export default NotificationButton;

Ainda não acabamos de construir o componente. Precisamos passar algumas props para o <Styled.Button>.

Dentro da tag de abertura, passaremos um evento de onClick, que define o que será executado quando for clicado. Nesse caso, vamos executar uma action, entre chaves.

Devemos receber essa action como parâmetro dentro dos parênteses da arrow function do componente NotificationButton na linha 4. Para desestruturar essa propriedade action, vamos envolvê-la entre chaves.

Outros props que passaremos para o componente <Styled.Button> serão os eventos de mouse chamados onMouseEnter e onMouseLeave. Assim, podemos especificar ações ao passar ou tirar o mouse de cima do componente.

No onMouseEnter, vamos passar uma função de callback, que é uma arrow function, onde utilizaremos o setExpanded(), trocando o valor para true. Similarmente, no onMouseLeave, vamos passar uma arrow function e digitar um setExpanded, mudando seu estado para false.

Além disso, precisamos a prop expanded por questão de estilo. Basta escrever $expanded igual a abre e fecha chaves. Nesse caso, será um pouco diferente, pois faremos uma verificação ternária.

Vamos verificar se temos o estado de expanded como true. Se sim, vamos retornar o valor de true, entre aspas. Se não, vamos retornar um undefined.

const NotificationButton = ({ action }) => {
    const [expanded, setExpanded] = useState(false);
    return (
        <Styled.ButtonWrapper>
            <Styled.Button
                onClick={action}
                onMouseEnter={() => setExpanded(true)}
                onMouseLeave={() => setExpanded(false)}
                $expanded={expanded ? "true" : undefined}
            >
                {expanded ? (
                    <Styled.Message $expanded={expanded}>
                        Receber Notificação
                    </Styled.Message>
                ) : (
                    <Styled.Interrogation>?</Styled.Interrogation>
                )}
            </Styled.Button>
        </Styled.ButtonWrapper>
    );
};

export default NotificationButton;

Feito isso, o componente está praticamente pronto. O ESLint informa um erro em action, com o qual não precisamos nos preocupar no momento.

Vamos testar esse botão no App.jsx?

Voltando no arquivo App.jsx, vamos importar o componente abaixo do Header, na linha 10. Basta digitar o nome do botão, <NotificationButton/>.

Devemos também verificar se ele foi importado do ./components/NotificationButton no começo do arquivo.

App.jsx:

import NotificationButton from "./components/NotificationButton";

function App() {
  const {} = useNotification();
  return (
    <>
      <Header />
      <NotificationButton/>
      <Outlet />
      <Footer />
    </>
  );
}

Após salvar a aplicação, voltamos ao navegador e recarregar a página.

Por enquanto, ainda aparece o pop-up para permitir notificações, mas no canto inferior esquerdo, já aparece um botão de interrogação. Se passamos o mouse por cima, aparece a mensagem de "Receber Notificação".

Próximos passos

Desenvolvemos um componente que será fundamental para garantir uma boa experiência da pessoa usuária, porque vamos utilizá-lo inicialmente para disparar uma notificação na tela.

Contudo, futuramente podemos utilizá-lo para exibir uma caixa de permissão ao ser clicado. Isso é uma boa regra de usabilidade para a aplicação.

No próximo vídeo, criaremos a lógica de disparar uma notificação quando clicarmos no botão, por exemplo, utilizando a API de Notification.

Sobre o curso React: implemente notificações push e sincronização em background

O curso React: implemente notificações push e sincronização em background possui 112 minutos de vídeos, em um total de 45 atividades. Gostou? Conheça nossos outros cursos de React em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda React acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas