Codelab da Web do Firebase

1. Visão Geral

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

3b1284f5144b54f6.png

O que você aprenderá

  • Sincronize dados usando Cloud Firestore e 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 editor de texto/IDE 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 de bate-papo da Web 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 ID 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 Firebase disponíveis para aplicativos da web:

  • Firebase Authentication para permitir facilmente que seus usuários façam login em seu aplicativo.
  • Cloud Firestore para salvar dados estruturados na nuvem e receber notificações instantâneas quando os dados forem alterados.
  • Armazenamento em nuvem para Firebase para salvar arquivos na nuvem.
  • Firebase Hosting para hospedar e atender seus ativos.
  • Firebase Cloud Messaging para enviar notificações push e exibir notificações pop-up do navegador.
  • Monitoramento de desempenho do Firebase para coletar dados de desempenho do usuário para seu aplicativo.

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

Adicionar um app 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 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

Ativar login do Google para Autenticação do Firebase

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, em seguida, 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 como Friendly Chat e escolha um e-mail de suporte do projeto no menu suspenso.
  5. Configure sua tela de consentimento OAuth no Google Cloud Console e adicione um logotipo:

d89fb3873b5d36ae.png

Ativar 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 Firebase console, clique em Firestore Database .
  2. Clique em Criar banco de dados no painel Cloud Firestore.

729991a081e7cd5.png

  1. Selecione a opção Iniciar no modo de teste e clique em Avançar após ler o aviso de isenção de responsabilidade 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 Cloud Storage para Firebase para armazenar, carregar 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 um botão Começar , isso 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 o aviso sobre as regras de segurança do seu projeto 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 seu 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 atender seu aplicativo da Web localmente, bem como 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

Certifique-se de que a versão do Firebase CLI seja 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 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 Firebase.

  1. Certifique-se de que sua linha de comando esteja acessando o diretório web-start local de seu aplicativo.
  2. Associe seu aplicativo ao seu projeto do Firebase executando o seguinte comando:
firebase use --add
  1. Quando solicitado, selecione o ID do projeto e atribua 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 da web pela primeira vez.

  1. Em um console do diretório web-start , execute o seguinte comando 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 Firebase Hosting para atender 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 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! Até agora, apenas apresentamos a IU para você.

Vamos agora construir um chat em tempo real!

6. Importe e configure o Firebase

Importar o SDK do Firebase

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

Vamos obter o Firebase SDK 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 carregue o mais rápido possível. Para este codelab, já criamos um arquivo web-start/package.json que inclui o Firebase SDK como uma dependência, bem como importamos 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, vamos usar Firebase Authentication, Cloud Firestore, Cloud Storage, Cloud Messaging e Performance Monitoring, então estamos importando todas as suas 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 sua compilação do 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 Firebase SDK
  4. Execute npm run start para iniciar o Webpack. O Webpack agora reconstruirá continuamente nosso código-fonte para o restante do codelab.

Configurar Firebase

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

  1. Acesse 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 trecho do Firebase SDK.
  4. Copie o snippet de 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á para 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 Firebase SDK 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 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());
}

Rastrear o estado de autenticação

Para atualizar nossa IU de acordo, 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). É nesse ponto que atualizaremos a interface do usuário para exibir ou ocultar o botão de login, o botão de logout, 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 e o nome de usuário do usuário conectado 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 IU seja atualizada de acordo. Ele chamará getProfilePicUrl e getUserName quando acionado.

  1. Volte para o arquivo src/index.js .
  2. Encontre 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, no entanto!) 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 exibido, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a exibir o aplicativo em http://localhost:5000 e, em seguida, 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 Google Sign-in como um provedor de autenticação no console do Firebase.
  3. Depois de entrar, sua foto de perfil e nome de usuário devem ser exibidos: c7401b3d44d0d78b.png

8. Escreva 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 bate-papo 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 chat 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 que clicar 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 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 exibido, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a exibir o aplicativo em http://localhost:5000 e, em seguida, abra-o em seu navegador.
  2. Depois de entrar, digite uma mensagem como "Olá!" e clique em ENVIAR . Isso gravará a mensagem no Cloud Firestore. No entanto, você ainda não verá os dados em seu aplicativo da 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 o Console do Firebase. Na seção Build , clique em Firestore Database (ou clique aqui e selecione seu projeto) e você verá a coleção de mensagens com sua mensagem recém-adicionada:

6812efe7da395692.png

9. Leia as mensagens

Sincronizar mensagens

Para ler as mensagens no aplicativo, precisamos adicionar ouvintes que são acionados 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 as 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 bate-papo 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 as mensagens no banco de dados, criamos uma consulta em uma coleção usando a função collection para especificar em qual coleção estão os dados que queremos ouvir. No código acima, estamos ouvindo as alterações nas messages coleção, que é onde as mensagens de chat 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 usa uma consulta como primeiro parâmetro e uma função de retorno de chamada como segundo. A função de retorno de chamada será acionada quando houver alguma alteração nos documentos que correspondam à consulta. Isso pode ocorrer se uma mensagem for excluída, modificada ou adicionada. Você pode ler mais sobre isso na documentação do Cloud Firestore .

Teste a sincronização de mensagens

  1. Se seu aplicativo ainda estiver sendo exibido, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a exibir o aplicativo em http://localhost:5000 e, em seguida, 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. Cloud Storage for Firebase é um serviço de armazenamento de arquivo/blob, e vamos usá-lo para armazenar todas as imagens que um usuário compartilhar usando nosso aplicativo.

Salvar imagens no Cloud Storage

Para este codelab, já adicionamos um botão que aciona uma caixa de diálogo do seletor de arquivos. Depois de 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 chat "placeholder" no feed de chat, para que os usuários vejam uma animação "Carregando" enquanto carregamos a imagem.
  2. Carrega o arquivo de imagem para o Cloud Storage neste caminho: /<uid>/<messageId>/<file_name>
  3. Gera um 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 no lugar da imagem de carregamento temporário.

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 de envio de imagens

  1. Se seu aplicativo ainda estiver sendo exibido, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a exibir o aplicativo em http://localhost:5000 e, em seguida, abra-o em seu navegador.
  2. Depois de entrar, 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 enquanto não estiver conectado, deverá ver uma notificação do Toast informando que você deve entrar 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 e sem nenhum custo.

Adicione o service worker do FCM

O aplicativo da web precisa de um service worker que receba e exiba 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 simplesmente precisa carregar e inicializar o Firebase Cloud Messaging SDK, que se encarregará de exibir as notificações.

Obter tokens de dispositivo FCM

Quando as notificações forem ativadas 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 faz login, chamamos a função saveMessagingDeviceToken . É aí que vamos obter o token do dispositivo FCM do navegador e salvá-lo 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, esse código não funcionará inicialmente. Para que seu app consiga recuperar o token do dispositivo, o usuário precisa conceder permissão ao app para mostrar notificações (próxima etapa do codelab).

Solicitar permissões para mostrar notificações

Quando o usuário ainda não concedeu permissão ao seu aplicativo 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 ( em navegadores compatíveis ).

8b9d0c66dc36153d.png

  1. Volte para o arquivo src/index.js .
  2. Encontre 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 exibido, atualize-o no navegador. Caso contrário, execute firebase serve --only hosting na linha de comando para começar a exibir o aplicativo em http://localhost:5000 e, em seguida, abra-o em seu navegador.
  2. Depois de entrar, 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 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. Insira 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 deverá aparecer em 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 do "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.

Neste momento, 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:

firestore.rules

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;
    }
  }
}

Atualize as 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 Firebase console:

  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

Veja as regras de segurança do Cloud Storage

Cloud Storage for Firebase 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 a regra de segurança padrão do Cloud Storage, que permite apenas que usuários autenticados usem o Cloud Storage. No console do Firebase , na guia Regras da seção Armazenamento , você pode visualizar e modificar as regras. Você deve ver a regra padrão que permite que qualquer usuário conectado leia e grave qualquer arquivo em seu depósito 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 do Cloud Storage
  • Certifique-se de que os arquivos enviados são imagens
  • Restrinja o tamanho das imagens que podem ser carregadas a no máximo 5 MB

Isso pode ser implementado usando as seguintes regras:

armazenamento.regras

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;
    }
  }
}

Atualize as regras de segurança do Cloud Storage

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

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

  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. (Os atributos hosting e database já devem 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 de monitoramento de desempenho para coletar dados de desempenho do mundo real de seu aplicativo e revisar e analisar esses dados no console do Firebase. O monitoramento de desempenho ajuda você a entender onde e quando o desempenho de seu aplicativo pode ser melhorado para que você possa usar essas informações para corrigir problemas de desempenho.

Há várias maneiras de integrar com o SDK JavaScript do Monitoramento de desempenho do Firebase. Neste codelab, habilitamos o monitoramento de desempenho de URLs de hospedagem . Consulte a documentação para ver outros métodos de ativação do SDK.

Traços automáticos

Como já importamos getPerformance na parte superior de web-start/src/index.js , precisamos apenas adicionar uma linha para instruir o Monitoramento de desempenho a coletar automaticamente o carregamento da página e as métricas de solicitação de rede para você quando os usuários visitam 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 primeiro atraso de entrada (opcional)

O atraso na primeira entrada é útil, pois o navegador que responde a uma interação do usuário dá a seus 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 após o navegador ser capaz de 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 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 primeiro polyfill de atraso de entrada, dê uma olhada na documentação .

Ver dados de desempenho

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

29389131150f33d7.png

Ao integrar o SDK de monitoramento de desempenho ao seu aplicativo, você não precisa escrever nenhum outro código antes que seu aplicativo comece a monitorar automaticamente vários aspectos críticos do desempenho. Para aplicativos da Web, o SDK registra aspectos como a primeira pintura do conteúdo, a capacidade dos 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 era necessária para fornecer 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 de seu aplicativo.
  2. Implante seus arquivos em seu 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 Firebase console do seu projeto para ver informações e ferramentas úteis sobre 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