Codelab da Web do Firebase

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

1. Visão Geral

Neste codelab, você aprenderá a usar o Firebase para criar aplicativos da Web com facilidade, implementando e implantando um cliente de bate-papo usando produtos e serviços do Firebase.

3b1284f5144b54f6.png

O que você vai aprender

  • Sincronize dados usando o Cloud Firestore e o Cloud Storage para Firebase.
  • Autentique seus usuários usando o Firebase Authentication.
  • Implante seu aplicativo da Web no Firebase Hosting.
  • Envie notificações com o Firebase Cloud Messaging.
  • Colete os dados de desempenho do seu aplicativo da web.

O que você precisará

  • O IDE/editor de texto de sua escolha, como WebStorm , Atom , Sublime ou VS Code
  • O gerenciador de pacotes npm , que normalmente vem com o Node.js
  • Um terminal/console
  • Um navegador de sua escolha, como o Chrome
  • O código de amostra do codelab (consulte a próxima etapa do codelab para saber como obter o código.)

2. Obtenha o código de amostra

Clone o repositório GitHub do codelab na linha de comando:

git clone https://github.com/firebase/codelab-friendlychat-web

Alternativamente, se você não tiver o git instalado, você pode baixar o repositório como um arquivo ZIP .

Importar o aplicativo inicial

Usando seu IDE, abra ou importe o diretório 📁 web-start do repositório clonado. Este 📁 diretório web-start contém o código inicial para o codelab, que será um aplicativo web de bate-papo totalmente funcional.

3. Crie e configure um projeto do Firebase

Criar um projeto do Firebase

  1. Faça login no Firebase .
  2. No console do Firebase, clique em Adicionar projeto e nomeie seu projeto do Firebase como FriendlyChat . Lembre-se do código do projeto do Firebase.
  3. Desmarque Ativar o Google Analytics para este projeto
  4. Clique em Criar projeto .

O aplicativo que vamos criar usa produtos do Firebase que estão disponíveis para aplicativos da Web:

  • Firebase Authentication para permitir que os usuários façam login no seu aplicativo com facilidade.
  • Cloud Firestore para salvar dados estruturados na nuvem e receber notificações instantâneas quando os dados forem alterados.
  • Cloud Storage para Firebase para salvar arquivos na nuvem.
  • Firebase Hosting para hospedar e servir seus recursos.
  • Firebase Cloud Messaging para enviar notificações push e exibir notificações pop-up do navegador.
  • Firebase Performance Monitoring para coletar dados de desempenho do usuário para seu aplicativo.

Alguns desses produtos precisam de configuração especial ou precisam ser ativados usando o Firebase console.

Adicionar um aplicativo da Web do Firebase ao projeto

  1. Clique no ícone da web 58d6543a156e56f9.png para criar um novo app da Web do Firebase.
  2. Registre o aplicativo com o apelido Friendly Chat e marque a caixa ao lado de Também configurar o Firebase Hosting para este aplicativo . Clique em Registrar aplicativo .
  3. Na próxima etapa, você verá um objeto de configuração. Copie apenas o objeto JS (não o HTML ao redor) em firebase-config.js

Registrar captura de tela do aplicativo da web

Ative o login do Google para o Firebase Authentication

Para permitir que os usuários façam login no aplicativo da web com suas contas do Google, usaremos o método de login do Google .

Você precisará ativar o login do Google :

  1. No console do Firebase, localize a seção Build no painel esquerdo.
  2. Clique em Autenticação e clique na guia Método de login (ou clique aqui para ir diretamente para lá).
  3. Ative o provedor de login do Google e clique em Salvar .
  4. Defina o nome público do seu aplicativo para Bate- papo amigável e escolha um e- mail de suporte do Project no menu suspenso.
  5. Configure sua tela de consentimento do OAuth no Console do Google Cloud e adicione um logotipo:

d89fb3873b5d36ae.png

Ativar o Cloud Firestore

O aplicativo da Web usa o Cloud Firestore para salvar mensagens de bate-papo e receber novas mensagens de bate-papo.

Você precisará ativar o Cloud Firestore:

  1. Na seção Build do console do Firebase, clique em Firestore Database .
  2. Clique em Criar banco de dados no painel do Cloud Firestore.

729991a081e7cd5.png

  1. Selecione a opção Iniciar no modo de teste e clique em Avançar depois de ler o aviso sobre as regras de segurança.

O modo de teste garante que possamos gravar livremente no banco de dados durante o desenvolvimento. Tornaremos nosso banco de dados mais seguro posteriormente neste codelab.

77e4986cbeaf9dee.png

  1. Defina o local onde seus dados do Cloud Firestore são armazenados. Você pode deixar isso como padrão ou escolher uma região próxima a você. Clique em Concluído para provisionar o Firestore.

9f2bb0d4e7ca49c7.png

Ativar armazenamento em nuvem

O aplicativo da Web usa o Cloud Storage para Firebase para armazenar, fazer upload e compartilhar fotos.

Você precisará ativar o Cloud Storage:

  1. Na seção Build do Firebase console, clique em Storage .
  2. Se não houver o botão Começar , significa que o armazenamento em nuvem já está ativado e você não precisa seguir as etapas abaixo.
  3. Clique em Começar .
  4. Leia a isenção de responsabilidade sobre as regras de segurança do seu projeto do Firebase e clique em Avançar .

Com as regras de segurança padrão, qualquer usuário autenticado pode gravar qualquer coisa no Cloud Storage. Tornaremos nosso armazenamento mais seguro posteriormente neste codelab.

62f1afdcd1260127.png

  1. O local do Cloud Storage é pré-selecionado com a mesma região que você escolheu para o banco de dados do Cloud Firestore. Clique em Concluído para concluir a configuração.

1d7f49ebaddb32fc.png

4. Instale a interface de linha de comando do Firebase

A interface de linha de comando (CLI) do Firebase permite que você use o Firebase Hosting para veicular seu aplicativo da Web localmente, bem como para implantar seu aplicativo da Web em seu projeto do Firebase.

  1. Instale a CLI executando o seguinte comando npm:
npm -g install firebase-tools
  1. Verifique se a CLI foi instalada corretamente executando o seguinte comando:
firebase --version

Verifique se a versão da Firebase CLI é v4.1.0 ou posterior.

  1. Autorize a Firebase CLI executando o seguinte comando:
firebase login

Configuramos o modelo de aplicativo da Web para extrair a configuração do seu aplicativo para o Firebase Hosting do diretório local do seu aplicativo (o repositório que você clonou anteriormente no codelab). Mas para puxar a configuração, precisamos associar seu aplicativo ao seu projeto do Firebase.

  1. Certifique-se de que sua linha de comando esteja acessando o diretório web-start local do seu aplicativo.
  2. Associe seu aplicativo ao projeto do Firebase executando o seguinte comando:
firebase use --add
  1. Quando solicitado, selecione o ID do projeto e dê um alias ao projeto do Firebase.

Um alias é útil se você tiver vários ambientes (produção, preparação etc.). No entanto, para este codelab, vamos usar apenas o alias de default .

  1. Siga as instruções restantes em sua linha de comando.

5. Execute o aplicativo inicial localmente

Agora que você importou e configurou seu projeto, está pronto para executar o aplicativo Web pela primeira vez.

  1. Em um console do diretório web-start , execute o seguinte comando da Firebase CLI:
firebase serve --only hosting
  1. Sua linha de comando deve exibir a seguinte resposta:
✔  hosting: Local server: http://localhost:5000

Estamos usando o emulador do Firebase Hosting para veicular nosso aplicativo localmente. O aplicativo da web agora deve estar disponível em http://localhost:5000 . Todos os arquivos localizados no subdiretório public são servidos.

  1. Usando seu navegador, abra seu aplicativo em http://localhost:5000 .

Você deve ver a interface do usuário do seu aplicativo FriendlyChat, que (ainda!) não está funcionando:

4c23f9475228cef4.png

O aplicativo não pode fazer nada agora, mas com sua ajuda fará em breve! Nós apenas apresentamos a interface do usuário para você até agora.

Vamos agora construir um bate-papo em tempo real!

6. Importe e configure o Firebase

Importar o SDK do Firebase

Precisamos importar o SDK do Firebase para o aplicativo. Existem várias maneiras de fazer isso, conforme descrito em nossa documentação . Por exemplo, você pode importar a biblioteca do nosso CDN. Ou você pode instalá-lo localmente usando o npm e empacotá-lo em seu aplicativo se estiver usando o Browserify.

Vamos obter o SDK do Firebase do npm e usar o Webpack para agrupar nosso código. Estamos fazendo isso para que o Webpack possa remover qualquer código desnecessário, mantendo o tamanho do pacote JS pequeno para garantir que nosso aplicativo seja carregado o mais rápido possível. Para este codelab, já criamos um arquivo web-start/package.json que inclui o SDK do Firebase como uma dependência, além de importar as funções necessárias na parte superior de web-start/src/index.js .

pacote.json

"dependencies": {
  "firebase": "^9.0.0"
}

index.js

import { initializeApp } from 'firebase/app';
import {
  getAuth,
  onAuthStateChanged,
  GoogleAuthProvider,
  signInWithPopup,
  signOut,
} from 'firebase/auth';
import {
  getFirestore,
  collection,
  addDoc,
  query,
  orderBy,
  limit,
  onSnapshot,
  setDoc,
  updateDoc,
  doc,
  serverTimestamp,
} from 'firebase/firestore';
import {
  getStorage,
  ref,
  uploadBytesResumable,
  getDownloadURL,
} from 'firebase/storage';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
import { getPerformance } from 'firebase/performance';

Durante este codelab, usaremos o Firebase Authentication, o Cloud Firestore, o Cloud Storage, o Cloud Messaging e o Performance Monitoring, por isso estamos importando todas as bibliotecas. Em seus aplicativos futuros, certifique-se de importar apenas as partes do Firebase necessárias para reduzir o tempo de carregamento do seu aplicativo.

Instale o SDK do Firebase e inicie a compilação do seu Webpack

Precisamos executar alguns comandos para iniciar a compilação do nosso aplicativo.

  1. Abra uma nova janela de terminal
  2. Verifique se você está no diretório web-start
  3. Execute npm install para baixar o SDK do Firebase
  4. Execute npm run start para iniciar o Webpack. O Webpack agora reconstruirá continuamente nosso código-fonte para o restante do codelab.

Configurar o Firebase

Também precisamos configurar o SDK do Firebase para informar qual projeto do Firebase estamos usando.

  1. Vá para as configurações do seu projeto no console do Firebase
  2. No cartão "Seus aplicativos", selecione o apelido do aplicativo para o qual você precisa de um objeto de configuração.
  3. Selecione "Config" no painel de snippets do SDK do Firebase.
  4. Copie o snippet do objeto de configuração e adicione-o a web-start/src/firebase-config.js .

firebase-config.js

const config = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  databaseURL: "https://PROJECT_ID.firebaseio.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.appspot.com",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  measurementId: "G-MEASUREMENT_ID",
};

Agora, vá até o final de web-start/src/index.js e inicialize o Firebase:

index.js

const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);

7. Configure o login do usuário

O SDK do Firebase agora deve estar pronto para uso, pois foi importado e inicializado em index.js . Agora vamos implementar o login do usuário usando o Firebase Authentication .

Autentique seus usuários com o Login do Google

No aplicativo, quando um usuário clica no botão Fazer login com o Google , a função de signIn é acionada. (Já configuramos isso para você!) Para este codelab, queremos autorizar o Firebase a usar o Google como provedor de identidade. Usaremos um pop-up, mas vários outros métodos estão disponíveis no Firebase.

  1. No diretório web-start , no subdiretório src/ , abra index.js .
  2. Encontre a função signIn .
  3. Substitua toda a função pelo código a seguir.

index.js

// Signs-in Friendly Chat.
async function signIn() {
  // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new GoogleAuthProvider();
  await signInWithPopup(getAuth(), provider);
}

A função signOut é acionada quando o usuário clica no botão Sair .

  1. Volte para o arquivo src/index.js .
  2. Encontre a função signOutUser .
  3. Substitua toda a função pelo código a seguir.

index.js

// Signs-out of Friendly Chat.
function signOutUser() {
  // Sign out of Firebase.
  signOut(getAuth());
}

Acompanhe o estado de autenticação

Para atualizar nossa interface de usuário adequadamente, precisamos de uma maneira de verificar se o usuário está conectado ou desconectado. Com o Firebase Authentication, você pode registrar um observador no estado de autenticação que será acionado sempre que o estado de autenticação for alterado.

  1. Volte para o arquivo src/index.js .
  2. Encontre a função initFirebaseAuth .
  3. Substitua toda a função pelo código a seguir.

index.js

// Initialize firebase auth
function initFirebaseAuth() {
  // Listen to auth state changes.
  onAuthStateChanged(getAuth(), authStateObserver);
}

O código acima registra a função authStateObserver como o observador do estado de autenticação. Ele será acionado sempre que o estado de autenticação for alterado (quando o usuário entrar ou sair). É neste ponto que atualizaremos a interface do usuário para exibir ou ocultar o botão de entrada, o botão de saída, a foto do perfil do usuário conectado e assim por diante. Todas essas partes da interface do usuário já foram implementadas.

Exibir as informações do usuário conectado

Queremos exibir a foto do perfil do usuário conectado e o nome de usuário na barra superior do nosso aplicativo. No Firebase, os dados do usuário conectado estão sempre disponíveis no objeto currentUser . Anteriormente, configuramos a função authStateObserver para ser acionada quando o usuário fizer login para que nossa interface do usuário seja atualizada de acordo. Ele chamará getProfilePicUrl e getUserName quando acionado.

  1. Volte para o arquivo src/index.js .
  2. Localize as funções getProfilePicUrl e getUserName .
  3. Substitua ambas as funções pelo código a seguir.

index.js

// Returns the signed-in user's profile Pic URL.
function getProfilePicUrl() {
  return getAuth().currentUser.photoURL || '/images/profile_placeholder.png';
}

// Returns the signed-in user's display name.
function getUserName() {
  return getAuth().currentUser.displayName;
}

Exibimos uma mensagem de erro se o usuário tentar enviar mensagens quando o usuário não estiver conectado. (Você pode tentar!) Portanto, precisamos detectar se o usuário está realmente conectado.

  1. Volte para o arquivo src/index.js .
  2. Encontre a função isUserSignedIn .
  3. Substitua toda a função pelo código a seguir.

index.js

// Returns true if a user is signed-in.
function isUserSignedIn() {
  return !!getAuth().currentUser;
}

Teste o login no aplicativo

  1. Se seu aplicativo ainda estiver sendo veiculado, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a servir o aplicativo em http://localhost:5000 e abra-o em seu navegador.
  2. Faça login no aplicativo usando o botão de login e sua conta do Google. Se você vir uma mensagem de erro informando auth/operation-not-allowed , verifique se ativou o Login do Google como um provedor de autenticação no console do Firebase.
  3. Após o login, sua foto de perfil e nome de usuário devem ser exibidos: c7401b3d44d0d78b.png

8. Gravar mensagens no Cloud Firestore

Nesta seção, gravaremos alguns dados no Cloud Firestore para que possamos preencher a IU do aplicativo. Isso pode ser feito manualmente com o console do Firebase , mas faremos isso no próprio aplicativo para demonstrar uma gravação básica do Cloud Firestore.

Modelo de dados

Os dados do Cloud Firestore são divididos em coleções, documentos, campos e subcoleções. Armazenaremos cada mensagem do chat como um documento em uma coleção de nível superior chamada messages .

688d7bc5fb662b57.png

Adicionar mensagens ao Cloud Firestore

Para armazenar as mensagens de bate-papo escritas pelos usuários, usaremos o Cloud Firestore .

Nesta seção, você adicionará a funcionalidade para que os usuários escrevam novas mensagens em seu banco de dados. Um usuário clicando no botão ENVIAR acionará o snippet de código abaixo. Ele adiciona um objeto de mensagem com o conteúdo dos campos de mensagem à sua instância do Cloud Firestore na coleção de messages . O método add() adiciona um novo documento com um ID gerado automaticamente à coleção.

  1. Volte para o arquivo src/index.js .
  2. Encontre a função saveMessage .
  3. Substitua toda a função pelo código a seguir.

index.js

// Saves a new message to Cloud Firestore.
async function saveMessage(messageText) {
  // Add a new message entry to the Firebase database.
  try {
    await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      text: messageText,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });
  }
  catch(error) {
    console.error('Error writing new message to Firebase Database', error);
  }
}

Teste o envio de mensagens

  1. Se seu aplicativo ainda estiver sendo veiculado, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a servir o aplicativo em http://localhost:5000 e abra-o em seu navegador.
  2. Depois de fazer login, digite uma mensagem como "E aí!" e clique em ENVIAR . Isso gravará a mensagem no Cloud Firestore. No entanto, você ainda não verá os dados em seu aplicativo Web real porque ainda precisamos implementar a recuperação dos dados (a próxima seção do codelab).
  3. Você pode ver a mensagem recém-adicionada no Firebase Console. Abra seu Console do Firebase. Na seção Build , clique em Firestore Database (ou clique aqui e selecione seu projeto) e você deverá ver a coleção de mensagens com sua mensagem recém-adicionada:

6812efe7da395692.png

9. Leia as mensagens

Sincronizar mensagens

Para ler mensagens no aplicativo, precisaremos adicionar ouvintes que acionam quando os dados são alterados e, em seguida, criar um elemento de interface do usuário que mostre novas mensagens.

Adicionaremos um código que detecta mensagens recém-adicionadas do aplicativo. Neste código, vamos registrar o ouvinte que escuta as alterações feitas nos dados. Mostraremos apenas as últimas 12 mensagens do chat para evitar a exibição de um histórico muito longo ao carregar.

  1. Volte para o arquivo src/index.js .
  2. Encontre a função loadMessages .
  3. Substitua toda a função pelo código a seguir.

index.js

// Loads chat messages history and listens for upcoming ones.
function loadMessages() {
  // Create the query to load the last 12 messages and listen for new ones.
  const recentMessagesQuery = query(collection(getFirestore(), 'messages'), orderBy('timestamp', 'desc'), limit(12));
  
  // Start listening to the query.
  onSnapshot(recentMessagesQuery, function(snapshot) {
    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        deleteMessage(change.doc.id);
      } else {
        var message = change.doc.data();
        displayMessage(change.doc.id, message.timestamp, message.name,
                      message.text, message.profilePicUrl, message.imageUrl);
      }
    });
  });
}

Para ouvir mensagens no banco de dados, criamos uma consulta em uma coleção usando a função collection para especificar em qual coleção os dados que queremos ouvir estão. No código acima, estamos ouvindo as alterações nas messages coleção, que é onde as mensagens de bate-papo são armazenadas. Também estamos aplicando um limite ouvindo apenas as últimas 12 mensagens usando .limit(12) e ordenando as mensagens por data usando orderBy('timestamp', 'desc') para obter as 12 mensagens mais recentes.

A função onSnapshot recebe uma consulta como seu primeiro parâmetro e uma função de retorno de chamada como seu segundo. A função de retorno de chamada será acionada quando houver alterações nos documentos que correspondam à consulta. Isso pode acontecer se uma mensagem for excluída, modificada ou adicionada. Você pode ler mais sobre isso na documentação do Cloud Firestore .

Testar mensagens de sincronização

  1. Se seu aplicativo ainda estiver sendo veiculado, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a servir o aplicativo em http://localhost:5000 e abra-o em seu navegador.
  2. As mensagens que você criou anteriormente no banco de dados devem ser exibidas na interface do usuário do FriendlyChat (veja abaixo). Sinta-se à vontade para escrever novas mensagens; eles devem aparecer instantaneamente.
  3. (Opcional) Você pode tentar excluir, modificar ou adicionar novas mensagens manualmente diretamente na seção Banco de dados do console do Firebase; quaisquer alterações devem ser refletidas na interface do usuário.

Parabéns! Você está lendo documentos do Cloud Firestore em seu aplicativo!

2168dec79b573d07.png

10. Envie imagens

Agora adicionaremos um recurso que compartilha imagens.

Embora o Cloud Firestore seja bom para armazenar dados estruturados, o Cloud Storage é mais adequado para armazenar arquivos. O Cloud Storage para Firebase é um serviço de armazenamento de arquivos/blobs e o usaremos para armazenar todas as imagens que um usuário compartilhar usando nosso aplicativo.

Salvar imagens no Cloud Storage

Para este codelab, já adicionamos para você um botão que aciona uma caixa de diálogo do seletor de arquivos. Após selecionar um arquivo, a função saveImageMessage é chamada e você pode obter uma referência ao arquivo selecionado. A função saveImageMessage realiza o seguinte:

  1. Cria uma mensagem de bate-papo "espaço reservado" no feed do bate-papo, para que os usuários vejam uma animação "Carregando" enquanto carregamos a imagem.
  2. Faz upload do arquivo de imagem para o Cloud Storage neste caminho: /<uid>/<messageId>/<file_name>
  3. Gera uma URL publicamente legível para o arquivo de imagem.
  4. Atualiza a mensagem de bate-papo com o URL do arquivo de imagem recém-carregado em vez da imagem de carregamento temporária.

Agora você adicionará a funcionalidade para enviar uma imagem:

  1. Volte para o arquivo src/index.js .
  2. Encontre a função saveImageMessage .
  3. Substitua toda a função pelo código a seguir.

index.js

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
async function saveImageMessage(file) {
  try {
    // 1 - We add a message with a loading icon that will get updated with the shared image.
    const messageRef = await addDoc(collection(getFirestore(), 'messages'), {
      name: getUserName(),
      imageUrl: LOADING_IMAGE_URL,
      profilePicUrl: getProfilePicUrl(),
      timestamp: serverTimestamp()
    });

    // 2 - Upload the image to Cloud Storage.
    const filePath = `${getAuth().currentUser.uid}/${messageRef.id}/${file.name}`;
    const newImageRef = ref(getStorage(), filePath);
    const fileSnapshot = await uploadBytesResumable(newImageRef, file);
    
    // 3 - Generate a public URL for the file.
    const publicImageUrl = await getDownloadURL(newImageRef);

    // 4 - Update the chat message placeholder with the image's URL.
    await updateDoc(messageRef,{
      imageUrl: publicImageUrl,
      storageUri: fileSnapshot.metadata.fullPath
    });
  } catch (error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  }
}

Teste o envio de imagens

  1. Se seu aplicativo ainda estiver sendo veiculado, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a servir o aplicativo em http://localhost:5000 e abra-o em seu navegador.
  2. Depois de fazer login, clique no botão de upload de imagem 13734cb66773e5a3.png e selecione um arquivo de imagem usando o seletor de arquivos. Se você está procurando uma imagem, sinta-se à vontade para usar esta bela imagem de uma xícara de café .
  3. Uma nova mensagem deve aparecer na interface do usuário do aplicativo com a imagem selecionada: 3b1284f5144b54f6.png

Se você tentar adicionar uma imagem sem estar conectado, deverá ver uma notificação Toast informando que você deve fazer login para adicionar imagens.

11. Mostrar notificações

Agora adicionaremos suporte para notificações do navegador. O aplicativo notificará os usuários quando novas mensagens forem postadas no chat. O Firebase Cloud Messaging (FCM) é uma solução de mensagens multiplataforma que permite entregar mensagens e notificações de forma confiável sem nenhum custo.

Adicione o service worker do FCM

O aplicativo Web precisa de um service worker que receberá e exibirá notificações da Web.

  1. No diretório web-start , no diretório src , abra firebase-messaging-sw.js .
  2. Adicione o seguinte conteúdo a esse arquivo.

firebase-messaging-sw.js

// Import and configure the Firebase SDK
import { initializeApp } from 'firebase/app';
import { getMessaging } from 'firebase/messaging/sw';
import { getFirebaseConfig } from './firebase-config';

const firebaseApp = initializeApp(getFirebaseConfig());
getMessaging(firebaseApp);
console.info('Firebase messaging service worker is set up');

O service worker só precisa carregar e inicializar o SDK do Firebase Cloud Messaging, que cuidará da exibição das notificações.

Obter tokens de dispositivo FCM

Quando as notificações forem habilitadas em um dispositivo ou navegador, você receberá um token de dispositivo . Este token de dispositivo é o que usamos para enviar uma notificação para um determinado dispositivo ou navegador específico.

Quando o usuário entra, chamamos a função saveMessagingDeviceToken . É aí que obteremos o token do dispositivo FCM do navegador e o salvaremos no Cloud Firestore.

  1. Volte para o arquivo src/index.js .
  2. Encontre a função saveMessagingDeviceToken .
  3. Substitua toda a função pelo código a seguir.

index.js

// Saves the messaging device token to Cloud Firestore.
async function saveMessagingDeviceToken() {
  try {
    const currentToken = await getToken(getMessaging());
    if (currentToken) {
      console.log('Got FCM device token:', currentToken);
      // Saving the Device Token to Cloud Firestore.
      const tokenRef = doc(getFirestore(), 'fcmTokens', currentToken);
      await setDoc(tokenRef, { uid: getAuth().currentUser.uid });

      // This will fire when a message is received while the app is in the foreground.
      // When the app is in the background, firebase-messaging-sw.js will receive the message instead.
      onMessage(getMessaging(), (message) => {
        console.log(
          'New foreground notification from Firebase Messaging!',
          message.notification
        );
      });
    } else {
      // Need to request permissions to show notifications.
      requestNotificationsPermissions();
    }
  } catch(error) {
    console.error('Unable to get messaging token.', error);
  };
}

No entanto, este código não funcionará inicialmente. Para que seu aplicativo possa recuperar o token do dispositivo, o usuário precisa conceder ao seu aplicativo permissão para mostrar notificações (próxima etapa do codelab).

Solicitar permissões para mostrar notificações

Quando o usuário ainda não concedeu ao seu aplicativo permissão para mostrar notificações, você não receberá um token de dispositivo. Nesse caso, chamamos o método firebase.messaging().requestPermission() , que exibirá uma caixa de diálogo do navegador solicitando essa permissão ( nos navegadores compatíveis ).

8b9d0c66dc36153d.png

  1. Volte para o arquivo src/index.js .
  2. Localize a função requestNotificationsPermissions .
  3. Substitua toda a função pelo código a seguir.

index.js

// Requests permissions to show notifications.
async function requestNotificationsPermissions() {
  console.log('Requesting notifications permission...');
  const permission = await Notification.requestPermission();
  
  if (permission === 'granted') {
    console.log('Notification permission granted.');
    // Notification permission granted.
    await saveMessagingDeviceToken();
  } else {
    console.log('Unable to get permission to notify.');
  }
}

Obtenha o token do seu dispositivo

  1. Se seu aplicativo ainda estiver sendo veiculado, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a servir o aplicativo em http://localhost:5000 e abra-o em seu navegador.
  2. Após o login, a caixa de diálogo de permissão de notificações deve aparecer: bd3454e6dbfb6723.png
  3. Clique em Permitir .
  4. Abra o console JavaScript do seu navegador. Você deve ver a seguinte mensagem: Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu
  5. Copie o token do seu dispositivo. Você precisará dele para a próxima etapa do codelab.

Envie uma notificação para o seu dispositivo

Agora que você tem o token do seu dispositivo, pode enviar uma notificação.

  1. Abra a guia Cloud Messaging do console do Firebase .
  2. Clique em "Nova notificação"
  3. Insira um título de notificação e um texto de notificação.
  4. No lado direito da tela, clique em "enviar uma mensagem de teste"
  5. Digite o token do dispositivo que você copiou do console JavaScript do seu navegador e clique no sinal de mais ("+")
  6. Clique em "teste"

Se seu aplicativo estiver em primeiro plano, você verá a notificação no console JavaScript.

Se seu aplicativo estiver em segundo plano, uma notificação deve aparecer no seu navegador, como neste exemplo:

de79e8638a45864c.png

12. Regras de segurança do Cloud Firestore

Exibir regras de segurança do banco de dados

O Cloud Firestore usa uma linguagem de regras específica para definir direitos de acesso, segurança e validações de dados.

Ao configurar o projeto Firebase no início deste codelab, optamos por usar as regras de segurança padrão "Modo de teste" para não restringir o acesso ao armazenamento de dados. No console do Firebase , na guia Regras da seção Banco de dados , você pode visualizar e modificar essas regras.

Agora, você deve ver as regras padrão, que não restringem o acesso ao armazenamento de dados. Isso significa que qualquer usuário pode ler e gravar em qualquer coleção em seu armazenamento de dados.

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

Atualizaremos as regras para restringir as coisas usando as seguintes regras:

regras do firestore

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // Messages:
    //   - Anyone can read.
    //   - Authenticated users can add and edit messages.
    //   - Validation: Check name is same as auth token and text length below 300 char or that imageUrl is a URL.
    //   - Deletes are not allowed.
    match /messages/{messageId} {
      allow read;
      allow create, update: if request.auth != null
                    && request.resource.data.name == request.auth.token.name
                    && (request.resource.data.text is string
                      && request.resource.data.text.size() <= 300
                      || request.resource.data.imageUrl is string
                      && request.resource.data.imageUrl.matches('https?://.*'));
      allow delete: if false;
    }
    // FCM Tokens:
    //   - Anyone can write their token.
    //   - Reading list of tokens is not allowed.
    match /fcmTokens/{token} {
      allow read: if false;
      allow write;
    }
  }
}

Atualizar regras de segurança do banco de dados

Há duas maneiras de editar as regras de segurança do banco de dados, no console do Firebase ou em um arquivo de regras local implantado usando a Firebase CLI.

Para atualizar as regras de segurança no console do Firebase:

  1. Vá para a seção Banco de Dados no painel esquerdo e clique na guia Regras .
  2. Substitua as regras padrão que já estão no console pelas regras mostradas acima.
  3. Clique em Publicar .

Para atualizar as regras de segurança de um arquivo local:

  1. No diretório web-start , abra firestore.rules .
  2. Substitua as regras padrão que já estão no arquivo pelas regras mostradas acima.
  3. No diretório web-start , abra firebase.json .
  4. Adicione o atributo firestore.rules apontando para firestore.rules , conforme mostrado abaixo. (O atributo hosting já deve estar no arquivo.)

firebase.json

{
  // Add this!
  "firestore": {
    "rules": "firestore.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. Implante as regras de segurança usando a Firebase CLI executando o seguinte comando:
firebase deploy --only firestore
  1. Sua linha de comando deve exibir a seguinte resposta:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  firestore: uploading rules firestore.rules...
✔  firestore: released rules firestore.rules to cloud.firestore

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

13. Regras de segurança do Cloud Storage

Ver regras de segurança do Cloud Storage

O Cloud Storage para Firebase usa uma linguagem de regras específica para definir direitos de acesso, segurança e validações de dados.

Ao configurar o projeto do Firebase no início deste codelab, optamos por usar a regra de segurança padrão do Cloud Storage que permite que apenas usuários autenticados usem o Cloud Storage. No console do Firebase , na guia Regras da seção Armazenamento , você pode visualizar e modificar regras. Você deve ver a regra padrão que permite que qualquer usuário conectado leia e grave qualquer arquivo em seu bucket de armazenamento.

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Atualizaremos as regras para fazer o seguinte:

  • Permitir que cada usuário grave apenas em suas próprias pastas específicas
  • Permitir que qualquer pessoa leia no Cloud Storage
  • Certifique-se de que os arquivos enviados são imagens
  • Restrinja o tamanho das imagens que podem ser carregadas a um máximo de 5 MB

Isso pode ser implementado usando as seguintes regras:

regras de armazenamento

rules_version = '2';

// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
  return request.resource.size < maxSizeMB * 1024 * 1024
      && request.resource.contentType.matches('image/.*');
}

service firebase.storage {
  match /b/{bucket}/o {
    match /{userId}/{messageId}/{fileName} {
      allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
      allow read;
    }
  }
}

Atualizar regras de segurança do Cloud Storage

Há duas maneiras de editar suas regras de segurança de armazenamento: no Firebase console ou em um arquivo de regras local implantado usando a Firebase CLI.

Para atualizar as regras de segurança no console do Firebase:

  1. Vá para a seção Armazenamento no painel esquerdo e clique na guia Regras .
  2. Substitua a regra padrão que já está no console pelas regras mostradas acima.
  3. Clique em Publicar .

Para atualizar as regras de segurança de um arquivo local:

  1. No diretório web-start , abra storage.rules .
  2. Substitua as regras padrão que já estão no arquivo pelas regras mostradas acima.
  3. No diretório web-start , abra firebase.json .
  4. Adicione o atributo storage.rules apontando para o arquivo storage.rules , conforme mostrado abaixo. (O atributo hosting e database já deve estar no arquivo.)

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // Add this!
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}
  1. Implante as regras de segurança usando a Firebase CLI executando o seguinte comando:
firebase deploy --only storage
  1. Sua linha de comando deve exibir a seguinte resposta:
=== Deploying to 'friendlychat-1234'...

i  deploying storage
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  storage: uploading rules storage.rules...
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview

14. Colete dados de desempenho

Você pode usar o SDK do Monitoramento de desempenho para coletar dados de desempenho do mundo real do seu aplicativo e, em seguida, revisar e analisar esses dados no console do Firebase. O Monitoramento de Desempenho ajuda você a entender onde e quando o desempenho do seu aplicativo pode ser melhorado para que você possa usar essas informações para corrigir problemas de desempenho.

Há várias formas de integração com o SDK do JavaScript do Firebase Performance Monitoring. Neste codelab, ativamos o Monitoramento de desempenho de URLs de hospedagem . Consulte a documentação para ver outros métodos de habilitação do SDK.

Rastreamentos automáticos

Como já importamos getPerformance na parte superior de web-start/src/index.js , só precisamos adicionar uma linha para informar ao Monitoramento de desempenho para coletar automaticamente o carregamento da página e as métricas de solicitação de rede para você quando os usuários visitarem seu site implantado!

  1. Em web-start/src/index.js , adicione a seguinte linha abaixo do TODO existente para inicializar o Monitoramento de desempenho.

index.js

// TODO: Enable Firebase Performance Monitoring.
getPerformance();

Meça o atraso da primeira entrada (opcional)

O atraso na primeira entrada é útil, pois o navegador que responde a uma interação do usuário dá aos usuários as primeiras impressões sobre a capacidade de resposta do seu aplicativo.

O atraso da primeira entrada começa quando o usuário interage pela primeira vez com um elemento na página, como clicar em um botão ou hiperlink. Ele para imediatamente depois que o navegador consegue responder à entrada, o que significa que o navegador não está ocupado carregando ou analisando o conteúdo da sua página.

Se você quiser medir o atraso da primeira entrada, precisará incluir o código a seguir diretamente.

  1. Abra public/index.html .
  2. Descomente a tag de script na linha a seguir.

index.html

<!-- TODO: Enable First Input Delay polyfill library. -->
<script type="text/javascript">!function(n,e){var t,o,i,c=[],f={passive:!0,capture:!0},r=new Date,a="pointerup",u="pointercancel";function p(n,c){t||(t=c,o=n,i=new Date,w(e),s())}function s(){o>=0&&o<i-r&&(c.forEach(function(n){n(o,t)}),c=[])}function l(t){if(t.cancelable){var o=(t.timeStamp>1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,o){function i(){p(t,o),r()}function c(){r()}function r(){e(a,i,f),e(u,c,f)}n(a,i,f),n(u,c,f)}(o,t):p(o,t)}}function w(n){["click","mousedown","keydown","touchstart","pointerdown"].forEach(function(e){n(e,l,f)})}w(n),self.perfMetrics=self.perfMetrics||{},self.perfMetrics.onFirstInputDelay=function(n){c.push(n),s()}}(addEventListener,removeEventListener);</script>

Para ler mais sobre o polyfill do primeiro atraso de entrada, dê uma olhada na documentação .

Ver dados de desempenho

Como você ainda não implantou seu site (você o implantará na próxima etapa), aqui está uma captura de tela mostrando as métricas sobre o desempenho de carregamento da página que você verá no console do Firebase 30 minutos após os usuários interagirem com seu site implantado :

29389131150f33d7.png

Ao integrar o SDK do Monitoramento de Desempenho em seu aplicativo, você não precisa escrever nenhum outro código antes que seu aplicativo comece a monitorar automaticamente vários aspectos críticos de desempenho. Para aplicativos da Web, o SDK registra aspectos como primeira pintura de conteúdo, capacidade de os usuários interagirem com seu aplicativo e muito mais.

Você também pode configurar rastreamentos, métricas e atributos personalizados para medir aspectos específicos do seu aplicativo. Visite a documentação para saber mais sobre rastreamentos e métricas personalizados e atributos personalizados .

15. Implante seu aplicativo usando o Firebase Hosting

O Firebase oferece um serviço de hospedagem para atender seus ativos e aplicativos da Web. Você pode implantar seus arquivos no Firebase Hosting usando a Firebase CLI. Antes de implantar, você precisa especificar em seu arquivo firebase.json quais arquivos locais devem ser implantados. Para este codelab, já fizemos isso para você porque esta etapa foi necessária para veicular nossos arquivos durante este codelab. As configurações de hospedagem são especificadas no atributo hosting :

firebase.json

{
  // If you went through the "Cloud Firestore Security Rules" step.
  "firestore": {
    "rules": "firestore.rules"
  },
  // If you went through the "Storage Security Rules" step.
  "storage": {
    "rules": "storage.rules"
  },
  "hosting": {
    "public": "./public"
  }
}

Essas configurações informam à CLI que queremos implantar todos os arquivos no diretório ./public ( "public": "./public" ).

  1. Certifique-se de que sua linha de comando esteja acessando o diretório web-start local do seu aplicativo.
  2. Implante seus arquivos no projeto do Firebase executando o seguinte comando:
firebase deploy --except functions
  1. O console deve exibir o seguinte:
=== Deploying to 'friendlychat-1234'...

i  deploying firestore, storage, hosting
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  firestore: checking firestore.rules for compilation errors...
✔  firestore: rules file firestore.rules compiled successfully
i  storage: uploading rules storage.rules...
i  firestore: uploading rules firestore.rules...
i  hosting[friendlychat-1234]: beginning deploy...
i  hosting[friendlychat-1234]: found 8 files in ./public
✔  hosting[friendlychat-1234]: file upload complete
✔  storage: released rules storage.rules to firebase.storage/friendlychat-1234.appspot.com
✔  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendlychat-1234]: finalizing version...
✔  hosting[friendlychat-1234]: version finalized
i  hosting[friendlychat-1234]: releasing new version...
✔  hosting[friendlychat-1234]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendlychat-1234/overview
Hosting URL: https://friendlychat-1234.firebaseapp.com
  1. Visite seu aplicativo da Web que agora está totalmente hospedado em uma CDN global usando o Firebase Hosting em dois de seus próprios subdomínios do Firebase:
  • https://<firebase-projectId>.firebaseapp.com
  • https://<firebase-projectId>.web.app

Como alternativa, você pode executar firebase open hosting:site na linha de comando.

Visite a documentação para saber mais sobre como o Firebase Hosting funciona .

Acesse a seção Hospedagem do console do Firebase do seu projeto para ver informações e ferramentas úteis de hospedagem, incluindo o histórico de suas implantações, a funcionalidade de reverter para versões anteriores do seu aplicativo e o fluxo de trabalho para configurar um domínio personalizado.

16. Parabéns!

Você usou o Firebase para criar um aplicativo da Web de bate-papo em tempo real!

O que cobrimos

  • Autenticação do Firebase
  • Cloud Firestore
  • SDK do Firebase para armazenamento em nuvem
  • Firebase Cloud Messaging
  • Monitoramento de desempenho do Firebase
  • Hospedagem Firebase

Próximos passos

Learn more