Conheça o Firebase para web

1. Visão Geral

Neste codelab, você vai aprender alguns dos princípios básicos de Firebase para criar aplicações web interativas. Você criará um RSVP de evento e um aplicativo de bate-papo de livro de visitas usando vários produtos Firebase.

59abdefbcc23bbbe.png

O que você aprenderá

  • Autentique usuários com Firebase Authentication e FirebaseUI.
  • Sincronize dados usando o Cloud Firestore.
  • Escreva regras de segurança do Firebase para proteger um banco de dados.

O que você precisará

  • Um navegador de sua escolha, como o Chrome.
  • Acesso a stackblitz.com (sem conta ou login necessário).
  • Uma conta do Google, como uma conta do gmail. Recomendamos a conta de e-mail que você já usa para sua conta do GitHub. Isso permite que você use recursos avançados no StackBlitz.
  • O código de amostra do codelab. Veja a próxima etapa para obter o código.

2. Obtenha o código inicial

Neste codelab, você constrói um aplicativo usando StackBlitz , um editor on-line que tem vários Firebase fluxos de trabalho integrados nela. Stackblitz não requer instalação de software ou conta StackBlitz especial.

StackBlitz permite que você compartilhe projetos com outras pessoas. Outras pessoas que têm a URL do seu projeto StackBlitz podem ver seu código e bifurcar seu projeto, mas não podem editar seu projeto StackBlitz.

  1. Ir para este URL para o código de partida: https://stackblitz.com/edit/firebase-gtk-web-start
  2. No topo da página StackBlitz, clique Fork: f5135360aef481cc.png

Agora você tem uma cópia do código inicial como seu próprio projeto StackBlitz. Desde que você não entrar, a sua conta é chamado @anonymous , mas o projeto tem um nome único, juntamente com uma URL única. Todos os seus arquivos e alterações são salvos neste projeto StackBlitz.

3. Edite as informações do evento

Os materiais iniciais para este codelab fornecem alguma estrutura para o aplicativo da web, incluindo algumas folhas de estilo e alguns contêineres HTML para o aplicativo. Posteriormente neste codelab, você conectará esses contêineres ao Firebase.

Para começar, vamos nos familiarizar um pouco mais com a interface StackBlitz.

  1. Em StackBlitz, abra o index.html arquivo.
  2. Localize event-details-container e description-container , e então tente editar algumas detalhes do evento.

Conforme você edita o texto, o recarregamento automático da página no StackBlitz exibe os novos detalhes do evento. Legal, certo?

<!-- ... -->

<div id="app">
  <img src="..." />

  <section id="event-details-container">
     <h1>Firebase Meetup</h1>

     <p><i class="material-icons">calendar_today</i> October 30</p>
     <p><i class="material-icons">location_city</i> San Francisco</p>

  </section>

  <hr>

  <section id="firebaseui-auth-container"></section>

  <section id="description-container">
     <h2>What we'll be doing</h2>
     <p>Join us for a day full of Firebase Workshops and Pizza!</p>
  </section>
</div>

<!-- ... -->

A visualização do seu aplicativo deve ser semelhante a esta:

Visualização do aplicativo

908cc57ce3a5b5fe.png

4. Crie e configure um projeto Firebase

Exibir as informações do evento é ótimo para seus convidados, mas apenas mostrar os eventos não é muito útil para ninguém. Vamos adicionar algumas funcionalidades dinâmicas a este aplicativo. Para isso, você precisa conectar o Firebase ao seu aplicativo. Para começar a usar o Firebase, você precisará criar e configurar um projeto do Firebase.

Crie um projeto Firebase

  1. Entrar no Firebase .
  2. No console Firebase, clique em Add Project (ou Criar um projeto), em seguida, nomeie o seu Firebase projeto Firebase-Web-Codelab.
    a67c239f8cc7f4b5.png
  3. Clique nas opções de criação do projeto. Aceite os termos do Firebase, se solicitado. Pule a configuração do Google Analytics, porque você não usará o Analytics para este aplicativo.

Para saber mais sobre os projetos Firebase, consulte Compreender projectos Firebase .

Ativar produtos Firebase no console

O aplicativo que você está construindo usa vários produtos Firebase que estão disponíveis para aplicativos da web:

  • Autenticação Firebase e Firebase UI para permitir facilmente seus usuários para acessar a sua aplicação.
  • Nuvem Firestore para salvar dados estruturados na nuvem e obter notificação instantânea quando alterações de dados.
  • Regras de Segurança Firebase para garantir a sua base de dados.

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

Ativar login de e-mail para Firebase Authentication

Para permitir que os usuários assinem na aplicação web, você vai usar o sign-in E-mail / senha método para este codelab:

  1. No console Firebase, clique em criar no painel esquerdo.
  2. Clique em Autenticação, clique no sinal-in guia método (ou clique aqui para ir diretamente para o Sign-in guia método).
  3. Clique E-mail / senha na lista de Sign-in fornecedores, coloque o interruptor para a posição Ativar, clique em Salvar.
    4c88427cfd869bee.png

Ativar Cloud Firestore

O aplicativo da Web usa Nuvem Firestore para guardar as mensagens de bate-papo e receber novas mensagens de chat.

Habilite o Cloud Firestore:

  1. Na seção de construção do o Firebase console, clique Firestore banco de dados.
  2. Clique em Criar banco de dados.
    3ce19fd6467e51c5.png
  3. Selecione a opção Iniciar o modo de teste no. Leia a isenção de responsabilidade sobre as regras de segurança. O modo de teste garante que você possa gravar livremente no banco de dados durante o desenvolvimento. Clique em Avançar.
    56369cebb9300eb.png
  4. Selecione o local para seu banco de dados (você pode apenas usar o padrão). Observe, porém, que este local não pode ser alterado posteriormente.
    32f815f4648c3174.png
  5. Clique em Concluído.

5. Adicione e configure o Firebase

Agora que você criou seu projeto do Firebase e ativou alguns serviços, precisa informar o código que deseja usar o Firebase, bem como qual projeto do Firebase usar.

Adicione as bibliotecas do Firebase

Para que seu aplicativo use o Firebase, você precisa adicionar as bibliotecas do Firebase ao aplicativo. Existem várias maneiras de fazer isso, como descrito na documentação Firebase . Por exemplo, você pode adicionar as bibliotecas do CDN do Google ou pode instalá-las localmente usando npm e empacotá-las em seu aplicativo se estiver usando o Browserify.

StackBlitz fornece empacotamento automático, para que você possa adicionar as bibliotecas do Firebase usando instruções de importação. Você usará as versões modulares (v9) das bibliotecas, que ajudam a reduzir o tamanho geral da página da Web por meio de um processo chamado "agitação da árvore". Você pode aprender mais sobre os SDKs modulares nos docs .

Para construir este aplicativo, você usa as bibliotecas Firebase Authentication, FirebaseUI e Cloud Firestore. Por esta codelab, as seguintes instruções de importação já estão incluídos no topo da index.js arquivo, e nós vamos estar importando mais métodos de cada biblioteca Firebase como vamos nós:

// Import stylesheets
import './style.css';

// Firebase App (the core Firebase SDK) is always required
import { initializeApp } from 'firebase/app';

// Add the Firebase products and methods that you want to use
import {} from 'firebase/auth';
import {} from 'firebase/firestore';

import * as firebaseui from 'firebaseui';

Adicionar um aplicativo da web do Firebase ao projeto

  1. Voltar no console Firebase, navegar a página de visão geral do seu projeto, clicando em Visão geral do projeto no canto superior esquerdo.
  2. No centro da página de visão geral do seu projeto, clique no ícone da web b286f3d215e1f578.png para criar um novo aplicativo da web do Firebase.
    c167e9526fad2825.png
  3. Registrar o aplicativo com o apelido Web App.
  4. Por esta codelab, fazer check NÃO a caixa ao lado também configurar Firebase hospedagem para esta aplicação. Você usará o painel de visualização do StackBlitz por enquanto.
  5. Clique Register aplicativo.
    c85ac8aa351e2560.png
  6. Copie o objeto de configuração Firebase para o clipboard.
    ed1e598c6132f734.png
  7. Clique em Continuar para consolar.

Adicione o objeto de configuração do Firebase ao seu aplicativo:

  1. Back in StackBlitz, vá para o index.js arquivo.
  2. Localize o Add Firebase project configuration object here linha de comentário, em seguida, cole o snippet de configuração, logo abaixo do comentário.
  3. Adicione o initializeApp chamada de função para configurar Firebase usando sua configuração única projecto Firebase.
    // ...
    // Add Firebase project configuration object here
    const firebaseConfig = {
      apiKey: "random-unique-string",
      authDomain: "your-projectId.firebaseapp.com",
      databaseURL: "https://your-projectId.firebaseio.com",
      projectId: "your-projectId",
      storageBucket: "your-projectId.appspot.com",
      messagingSenderId: "random-unique-string",
      appId: "random-unique-string",
    };
    
    // Initialize Firebase
    initializeApp(firebaseConfig);
    

6. Adicionar login de usuário (RSVP)

Agora que você adicionou Firebase para o aplicativo, você pode configurar um botão de RSVP que registra pessoas que usam autenticação Firebase .

Autentique seus usuários com login de e-mail e FirebaseUI

Você precisará de um botão RSVP que solicita que o usuário faça login com seu endereço de e-mail. Você pode fazer isso por ligar FirebaseUI a um button.FirebaseUI RSVP é uma biblioteca que lhe dá uma interface de usuário pré-construída em cima de Firebase Auth.

FirebaseUI requer uma configuração (veja as opções na documentação ), que faz duas coisas:

  • Diz FirebaseUI que você quiser usar o sign-in E-mail / senha método.
  • Lida com o retorno de chamada para um login bem-sucedido e retorna falso para evitar um redirecionamento. Você não deseja que a página seja atualizada porque está construindo um aplicativo da web de uma única página.

Adicione o código para inicializar FirebaseUI Auth

  1. Em StackBlitz, vá para o index.js arquivo.
  2. No topo, localize o firebase/auth declaração de importação, em seguida, adicione getAuth e EmailAuthProvider , assim:
    // ...
    // Add the Firebase products and methods that you want to use
    import { getAuth, EmailAuthProvider } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. Salvar uma referência para o objeto auth logo após initializeApp , assim:
    initializeApp(firebaseConfig);
    auth = getAuth();
    
  4. Observe que a configuração FirebaseUI já é fornecida no código inicial. Já está configurado para usar o provedor de autenticação de e-mail.
  5. Na parte inferior do main() função em index.js , adicione a instrução de inicialização FirebaseUI, assim:
    async function main() {
      // ...
    
      // Initialize the FirebaseUI widget using Firebase
      const ui = new firebaseui.auth.AuthUI(auth);
    }
    main();
    
    

Adicione um botão RSVP ao HTML

  1. Em StackBlitz, vá para o index.html arquivo.
  2. Adicione o HTML para um botão de RSVP dentro do event-details-container como mostrado no exemplo abaixo.

    Tenha o cuidado de usar as mesmas id valores como mostrado abaixo já porque, para este codelab, existem ganchos para essas identificações específicas no index.js arquivo.

    Note-se que na index.html arquivo, há um recipiente com a ID firebaseui-auth-container . Este é o ID que você passará para FirebaseUI para manter seu login.
    <!-- ... -->
    
    <section id="event-details-container">
        <!-- ... -->
        <!-- ADD THE RSVP BUTTON HERE -->
        <button id="startRsvp">RSVP</button>
    </section>
    <hr>
    <section id="firebaseui-auth-container"></section>
    <!-- ... -->
    
    App prévia
    ab9ad7d61bb7b28c.png
  3. Configure um ouvinte no botão RSVP e chame a função de início FirebaseUI. Isso informa ao FirebaseUI que você deseja ver a janela de login.

    Adicione o seguinte código para a parte inferior do main() função em index.js :
    async function main() {
      // ...
    
      // Listen to RSVP button clicks
      startRsvpButton.addEventListener("click",
       () => {
            ui.start("#firebaseui-auth-container", uiConfig);
      });
    }
    main();
    

Teste o login no aplicativo

  1. Na janela de visualização do StackBlitz, clique no botão RSVP para entrar no aplicativo.
    • Para este codelab, você pode usar qualquer endereço de e-mail, até mesmo um endereço de e-mail falso, já que não está configurando uma etapa de verificação de e-mail para este codelab.
    • Se você ver uma mensagem de erro informando auth/operation-not-allowed ou The given sign-in provider is disabled for this Firebase project , certifique-se que você habilitou-mail / senha como um sinal-in provedor no console Firebase.
    Visualização do aplicativo
    3024f90b52ad55fe.png
  2. Vá para o painel de autenticação no console Firebase. Na guia Usuários, você deve ver as informações da conta que você inseriu ao sinal na aplicação. 682fc0eca86a99fc.png

Adicionar estado de autenticação à IU

Em seguida, certifique-se de que a IU reflete o fato de que você está conectado.

Você usará o callback do listener de estado do Firebase Authentication, que é notificado sempre que o status de login do usuário muda. Se houver um usuário conectado no momento, seu aplicativo mudará o botão "RSVP" para o botão "logout".

  1. Em StackBlitz, vá para o index.js arquivo.
  2. No topo, localize o firebase/auth declaração de importação, em seguida, adicione signOut e onAuthStateChanged , assim:
    // ...
    // Add the Firebase products and methods that you want to use
    import {
      getAuth,
      EmailAuthProvider,
      signOut,
      onAuthStateChanged
    } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. Adicionar o seguinte código na parte inferior da main() função:
    async function main() {
      // ...
    
      // Listen to the current Auth state
      onAuthStateChanged(auth, user => {
        if (user) {
          startRsvpButton.textContent = 'LOGOUT';
        } else {
          startRsvpButton.textContent = 'RSVP';
        }
      });
    }
    main();
    
  4. No listener de botão, verifique se há um usuário atual e faça logout. Para fazer isso, substituir o atual startRsvpButton.addEventListener com o seguinte:
    // ...
    // Called when the user clicks the RSVP button
    startRsvpButton.addEventListener('click', () => {
      if (auth.currentUser) {
        // User is signed in; allows user to sign out
        signOut(auth);
      } else {
        // No user is signed in; allows user to sign in
        ui.start('#firebaseui-auth-container', uiConfig);
      }
    });
    

Agora, o botão em seu aplicativo deve mostrar LOGOUT, e deve voltar a RSVP quando é clicado.

Visualização do aplicativo

4c540450924f1607.png

7. Escreva mensagens para o Cloud Firestore

Saber que os usuários estão chegando é ótimo, mas vamos dar aos convidados algo mais para fazer no aplicativo. E se eles pudessem deixar mensagens em um livro de visitas? Eles podem compartilhar por que estão ansiosos para vir ou quem eles esperam encontrar.

Para armazenar as mensagens de bate-papo que os usuários escrevem no app, você vai usar Nuvem Firestore .

Modelo de dados

O Cloud Firestore é um banco de dados NoSQL e os dados armazenados no banco de dados são divididos em coleções, documentos, campos e subcoleções. Você irá armazenar cada mensagem do chat como um documento em uma coleção de nível superior chamado guestbook .

b447950f9f993789.png

Adicionar mensagens ao Firestore

Nesta seção, você adicionará a funcionalidade para que os usuários gravem novas mensagens no banco de dados. Primeiro, você adiciona o HTML para os elementos da IU (campo de mensagem e botão de envio). Em seguida, você adiciona o código que conecta esses elementos ao banco de dados.

Para adicionar os elementos da IU de um campo de mensagem e um botão de envio:

  1. Em StackBlitz, vá para o index.html arquivo.
  2. Localize o guestbook-container , em seguida, adicione o seguinte código HTML para criar um formulário com o campo de entrada de mensagem e no botão enviar.
    <!-- ... -->
    
     <section id="guestbook-container">
       <h2>Discussion</h2>
    
       <form id="leave-message">
         <label>Leave a message: </label>
         <input type="text" id="message">
         <button type="submit">
           <i class="material-icons">send</i>
           <span>SEND</span>
         </button>
       </form>
    
     </section>
    
    <!-- ... -->
    

Visualização do aplicativo

4a892284443cf73d.png

Um usuário clicar no botão ENVIAR irá acionar o trecho de código abaixo. Acrescenta o conteúdo do campo de entrada de mensagem para o guestbook coleção de banco de dados. Especificamente, o addDoc método adiciona o conteúdo da mensagem para um novo documento (com um ID gerado automaticamente) ao guestbook coleção.

  1. Em StackBlitz, vá para o index.js arquivo.
  2. No topo, localize o firebase/firestore declaração de importação, em seguida, adicione getFirestore , addDoc e collection , assim:
    // ...
    
    // Add the Firebase products and methods that you want to use
    import {
      getAuth,
      EmailAuthProvider,
      signOut,
      onAuthStateChanged
    } from 'firebase/auth';
    
    import {
      getFirestore,
      addDoc,
      collection
    } from 'firebase/firestore';
    
  3. Agora vamos salvar uma referência para o Firestore db certo objeto depois initializeApp :
    initializeApp(firebaseConfig);
    auth = getAuth();
    db = getFirestore();
    
  4. Na parte inferior do main() função, adicione o seguinte código.

    Note-se que auth.currentUser.uid é uma referência para a identificação única gerada automaticamente que a autenticação Firebase dá para todos os usuários conectados.
    async function main() {
      // ...
    
      // Listen to the form submission
      form.addEventListener('submit', async e => {
        // Prevent the default form redirect
        e.preventDefault();
        // Write a new message to the database collection "guestbook"
        addDoc(collection(db, 'guestbook'), {
          text: input.value,
          timestamp: Date.now(),
          name: auth.currentUser.displayName,
          userId: auth.currentUser.uid
        });
        // clear message input field
        input.value = '';
        // Return false to avoid redirect
        return false;
      });
    }
    main();
    

Mostrar o livro de visitas apenas para usuários conectados

Você não quer apenas alguém para ver bate-papo dos hóspedes. Uma coisa que você pode fazer para proteger o bate-papo é permitir que apenas usuários conectados vejam o livro de visitas. Dito isto, para seus próprios aplicativos, você vai querer também proteger o seu banco de dados com regras de segurança de Firebase . (Há mais informações sobre regras de segurança posteriormente no codelab.)

  1. Em StackBlitz, vá para o index.js arquivo.
  2. Edite o onAuthStateChanged ouvinte para ocultar e mostrar o livro de visitas.
    // ...
    
    // Listen to the current Auth state
    onAuthStateChanged(auth, user => {
      if (user) {
        startRsvpButton.textContent = 'LOGOUT';
        // Show guestbook to logged-in users
        guestbookContainer.style.display = 'block';
      } else {
        startRsvpButton.textContent = 'RSVP';
        // Hide guestbook for non-logged-in users
        guestbookContainer.style.display = 'none';
      }
    });
    

Teste o envio de mensagens

  1. Certifique-se de que você esteja conectado ao aplicativo.
  2. Digite uma mensagem como "Hey lá!", Em seguida, clique em Enviar.

Esta ação grava a mensagem em seu banco de dados do Cloud Firestore. No entanto, você ainda não verá a mensagem em seu aplicativo da web real porque ainda precisa implementar a recuperação dos dados. Você fará isso a seguir.

Mas você pode ver a mensagem recém-adicionada no console do Firebase.

No console Firebase, no painel de banco de dados , você deve ver o guestbook coleção com a sua mensagem recém-adicionado. Se você continuar enviando mensagens, sua coleção de livros de visitas conterá muitos documentos, como este:

Console do Firebase

713870af0b3b63c.png

8. Leia as mensagens

Sincronizar mensagens

É ótimo que os convidados possam escrever mensagens no banco de dados, mas ainda não as possam ver no aplicativo.

Para exibir mensagens, você precisará adicionar ouvintes que são acionados quando os dados mudam e, em seguida, criar um elemento de IU que mostra novas mensagens.

Você adicionará um código que escuta as mensagens recém-adicionadas do aplicativo. Primeiro, adicione uma seção no HTML para mostrar as mensagens:

  1. Em StackBlitz, vá para o index.html arquivo.
  2. No guestbook-container , adicione uma nova seção com o ID de guestbook .
    <!-- ... -->
    
      <section id="guestbook-container">
       <h2>Discussion</h2>
    
       <form><!-- ... --></form>
    
       <section id="guestbook"></section>
    
     </section>
    
    <!-- ... -->
    

Em seguida, registre o ouvinte que escuta as alterações feitas nos dados:

  1. Em StackBlitz, vá para o index.js arquivo.
  2. No topo, localize o firebase/firestore declaração de importação, em seguida, adicione query , orderBy e onSnapshot , assim:
    // ...
    import {
      getFirestore,
      addDoc,
      collection,
      query,
      orderBy,
      onSnapshot
    } from 'firebase/firestore';
    
  3. Na parte inferior do main() função, adicione o seguinte código para percorrer todos os documentos (mensagens de livro de visitas) no banco de dados. Para saber mais sobre o que está acontecendo neste código, leia as informações abaixo do snippet.
    async function main() {
      // ...
    
      // Create query for messages
      const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc'));
      onSnapshot(q, snaps => {
        // Reset page
        guestbook.innerHTML = '';
        // Loop through documents in database
        snaps.forEach(doc => {
          // Create an HTML entry for each document and add it to the chat
          const entry = document.createElement('p');
          entry.textContent = doc.data().name + ': ' + doc.data().text;
          guestbook.appendChild(entry);
        });
      });
    }
    main();
    

Para ouvir as mensagens no banco de dados, você criou uma consulta em uma coleção específica usando a collection função. O código acima escutas para as mudanças no guestbook coleção, que é onde as mensagens de bate-papo são armazenadas. As mensagens também são ordenados por data, usando orderBy('timestamp', 'desc') para exibir as mensagens mais recentes no topo.

O onSnapshot função tem dois parâmetros: a consulta para uso e uma função de chamada de retorno. A função de retorno de chamada é acionada quando há alguma alteração nos documentos que correspondem à consulta. Isso pode acontecer se uma mensagem for excluída, modificada ou adicionada. Para mais informações, consulte a documentação Nuvem Firestore .

Testar mensagens de sincronização

O Cloud Firestore sincroniza dados de forma automática e instantânea com clientes inscritos no banco de dados.

  • As mensagens que você criou anteriormente no banco de dados devem ser exibidas no aplicativo. Sinta-se à vontade para escrever novas mensagens; eles devem aparecer instantaneamente.
  • Se você abrir seu espaço de trabalho em várias janelas ou guias, as mensagens serão sincronizadas em tempo real entre as guias.
  • (Opcional) Você pode tentar manualmente apagar, modificar ou adicionar novas mensagens diretamente na seção Banco de Dados do console Firebase; todas as alterações devem aparecer na IU.

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

Visualização do aplicativo

e30df0a9614bae7d.png

9. Configure regras básicas de segurança

Você inicialmente configurou o Cloud Firestore para usar o modo de teste, o que significa que seu banco de dados está aberto para leituras e gravações. No entanto, você só deve usar o modo de teste durante os estágios iniciais de desenvolvimento. Como prática recomendada, você deve configurar regras de segurança para seu banco de dados à medida que desenvolve seu aplicativo. A segurança deve ser parte integrante da estrutura e do comportamento do seu aplicativo.

As regras de segurança permitem que você controle o acesso a documentos e coleções em seu banco de dados. A sintaxe de regras flexíveis permite criar regras que correspondem a qualquer coisa, desde todas as gravações em todo o banco de dados até operações em um documento específico.

Você pode escrever regras de segurança para o Cloud Firestore no Firebase console:

  1. Na seção de construção do o Firebase console, clique Firestore banco de dados, selecione a guia Regras (ou clique aqui para ir diretamente à guia Regras).
  2. Você deve ver as seguintes regras de segurança padrão, junto com um aviso sobre as regras serem públicas.

7767a2d2e64e7275.png

Identificar coleções

Primeiro, identifique as coleções nas quais o aplicativo grava dados.

Em match /databases/{database}/documents , identificar a coleção que você deseja proteger:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
     // You'll add rules here in the next step.
  }
}

Adicionar regras de segurança

Como você usou o UID de autenticação como um campo em cada documento do livro de visitas, você pode obter o UID de autenticação e verificar se qualquer pessoa que tentar gravar no documento possui um UID de autenticação correspondente.

Adicione as regras de leitura e gravação ao seu conjunto de regras, conforme mostrado abaixo:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow create:
        if request.auth.uid == request.resource.data.userId;
    }
  }
}

Agora, para o livro de visitas, apenas usuários conectados podem ler mensagens (qualquer mensagem!), Mas você só pode criar uma mensagem usando seu ID de usuário. Também não permitimos que as mensagens sejam editadas ou excluídas.

Adicionar regras de validação

Adicione validação de dados para garantir que todos os campos esperados estejam presentes no documento:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow create:
      if request.auth.uid == request.resource.data.userId
          && "name" in request.resource.data
          && "text" in request.resource.data
          && "timestamp" in request.resource.data;
    }
  }
}

Redefinir ouvintes

Porque seu aplicativo agora os usuários só permite autenticados fazer o login, você deve mover o livro de visitas firestore consulta dentro do ouvinte de autenticação. Caso contrário, ocorrerão erros de permissão e o aplicativo será desconectado quando o usuário fizer logout.

  1. Puxe a coleção guestbook onSnapshot ouvinte em uma nova função chamada subscribeGuestbook . Além disso, atribuir os resultados da onSnapshot função ao guestbookListener variável.

    O Firestore onSnapshot ouvinte retorna uma função de cancelamento que você vai ser capaz de usar para cancelar o ouvinte instantâneo mais tarde.
    // ...
    // Listen to guestbook updates
    // Listen to guestbook updates
    function subscribeGuestbook() {
      const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc'));
      guestbookListener = onSnapshot(q, snaps => {
        // Reset page
        guestbook.innerHTML = '';
        // Loop through documents in database
        snaps.forEach(doc => {
          // Create an HTML entry for each document and add it to the chat
          const entry = document.createElement('p');
          entry.textContent = doc.data().name + ': ' + doc.data().text;
          guestbook.appendChild(entry);
        });
      });
    }
    
  2. Adicionar um novo debaixo função chamada unsubscribeGuestbook . Verifique se o guestbookListener variável não é nulo, em seguida, chamar a função de cancelar o ouvinte.
    // ...
    // Unsubscribe from guestbook updates
    function unsubscribeGuestbook() {
      if (guestbookListener != null) {
        guestbookListener();
        guestbookListener = null;
      }
    }
    

Finalmente, adicione as novas funções ao onAuthStateChanged callback.

  1. Adicionar subscribeGuestbook() na parte inferior do if (user) .
  2. Adicionar unsubscribeGuestbook() na parte inferior da else declaração.
    // ...
    // Listen to the current Auth state
    onAuthStateChanged(auth, user => {
      if (user) {
        startRsvpButton.textContent = 'LOGOUT';
        // Show guestbook to logged-in users
        guestbookContainer.style.display = 'block';
        // Subscribe to the guestbook collection
        subscribeGuestbook();
      } else {
        startRsvpButton.textContent = 'RSVP';
        // Hide guestbook for non-logged-in users
        guestbookContainer.style.display = 'none';
        // Unsubscribe from the guestbook collection
        unsubscribeGuestbook();
      }
    });
    

10. Etapa bônus: pratique o que você aprendeu

Registre o status RSVP de um participante

No momento, seu aplicativo apenas permite que as pessoas comecem a bater papo se estiverem interessadas no evento. Além disso, a única maneira de saber se alguém está vindo é postar no chat. Vamos nos organizar e informar às pessoas quantas pessoas virão.

Você adicionará um botão de alternância para registrar as pessoas que desejam participar do evento e, em seguida, coletará uma contagem de quantas pessoas comparecerão.

  1. Em StackBlitz, vá para o index.html arquivo.
  2. No guestbook-container , adicione um conjunto de botões Sim e Não, assim:
    <!-- ... -->
      <section id="guestbook-container">
       <h2>Are you attending?</h2>
         <button id="rsvp-yes">YES</button>
         <button id="rsvp-no">NO</button>
    
       <h2>Discussion</h2>
    
       <!-- ... -->
    
     </section>
    <!-- ... -->
    

Visualização do aplicativo

73ca99ca35c13ee7.png

Em seguida, registre o ouvinte para cliques de botão. Se o usuário clicar em SIM, em seguida, usar o seu UID autenticação para salvar a resposta para o banco de dados.

  1. Em StackBlitz, vá para o index.js arquivo.
  2. No topo, localize o firebase/firestore declaração de importação, em seguida, adicione doc , setDoc , e where , assim:
    // ...
    // Add the Firebase products and methods that you want to use
    import {
      getFirestore,
      addDoc,
      collection,
      query,
      orderBy,
      onSnapshot,
      doc,
      setDoc,
      where
    } from 'firebase/firestore';
    
  3. Na parte inferior do main() função, adicione o seguinte código para ouvir o status RSVP:
    async function main() {
      // ...
    
      // Listen to RSVP responses
      rsvpYes.onclick = async () => {
      };
      rsvpNo.onclick = async () => {
      };
    }
    main();
    
    
  4. Criar uma nova coleção chamada attendees , em seguida, registrar uma referência de documento se qualquer botão RSVP é clicado.
  5. Definir que a referência a true ou false , dependendo de qual botão é clicado.

    Primeiro, para rsvpYes :
    // ...
    // Listen to RSVP responses
    rsvpYes.onclick = async () => {
      // Get a reference to the user's document in the attendees collection
      const userRef = doc(db, 'attendees', auth.currentUser.uid);
    
      // If they RSVP'd yes, save a document with attendi()ng: true
      try {
        await setDoc(userRef, {
          attending: true
        });
      } catch (e) {
        console.error(e);
      }
    };
    
    Em seguida, o mesmo para rsvpNo , mas com o valor false :
    rsvpNo.onclick = async () => {
      // Get a reference to the user's document in the attendees collection
      const userRef = doc(db, 'attendees', auth.currentUser.uid);
    
      // If they RSVP'd yes, save a document with attending: true
      try {
        await setDoc(userRef, {
          attending: false
        });
      } catch (e) {
        console.error(e);
      }
    };
    

Adicionar regras

Como você já tem algumas regras configuradas, os novos dados que você está adicionando com os botões serão rejeitados. Você precisa atualizar as regras para permitir a adição ao attendees coleção.

Para a attendees coleção, desde que você usou o UID de autenticação como o nome do documento, você pode agarrá-lo e verificar se o apresentador uid é o mesmo que o documento que está escrevendo. Você permitirá que todos leiam a lista de participantes (já que não há dados privados lá), mas apenas o criador deve ser capaz de atualizá-la.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId;
    }
  }
}

Adicionar regras de validação

Adicione validação de dados para garantir que todos os campos esperados estejam presentes no documento:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId
          && "attending" in request.resource.data;

    }
  }
}

(Opcional) Você pode agora ver os resultados de clicar nos botões. Acesse o painel do Cloud Firestore no Firebase console.

Leia o status RSVP

Agora que você registrou as respostas, vamos ver quem está vindo e refletir isso na IU.

  1. Em StackBlitz, vá para o index.html arquivo.
  2. Na description-container , adicionar um novo elemento com a identificação do number-attending .
    <!-- ... -->
    
     <section id="description-container">
         <!-- ... -->
         <p id="number-attending"></p>
     </section>
    
    <!-- ... -->
    

Em seguida, registrar o ouvinte para o attendees coleta e contar o número de respostas SIM:

  1. Em StackBlitz, vá para o index.js arquivo.
  2. Na parte inferior do main() função, adicione o seguinte código para ouvir o status de RSVP e contar cliques SIM.
    async function main() {
      // ...
    
      // Listen for attendee list
      const attendingQuery = query(
        collection(db, 'attendees'),
        where('attending', '==', true)
      );
      const unsubscribe = onSnapshot(attendingQuery, snap => {
        const newAttendeeCount = snap.docs.length;
        numberAttending.innerHTML = newAttendeeCount + ' people going';
      });
    }
    main();
    

Por fim, vamos destacar o botão correspondente ao status atual.

  1. Criar uma função que verifica se o atual UID de autenticação tem uma entrada no attendees coleção, em seguida, definir a classe botão para clicked .
    // ...
    // Listen for attendee list
    function subscribeCurrentRSVP(user) {
      const ref = doc(db, 'attendees', user.uid);
      rsvpListener = onSnapshot(ref, doc => {
        if (doc && doc.data()) {
          const attendingResponse = doc.data().attending;
    
          // Update css classes for buttons
          if (attendingResponse) {
            rsvpYes.className = 'clicked';
            rsvpNo.className = '';
          } else {
            rsvpYes.className = '';
            rsvpNo.className = 'clicked';
          }
        }
      });
    }
    
  2. Além disso, vamos fazer uma função para cancelar a assinatura. Isso será usado quando o usuário fizer logout.
    // ...
    function unsubscribeCurrentRSVP() {
      if (rsvpListener != null) {
        rsvpListener();
        rsvpListener = null;
      }
      rsvpYes.className = '';
      rsvpNo.className = '';
    }
    
  3. Chame as funções do ouvinte de autenticação.
    // ...
    // Listen to the current Auth state
      // Listen to the current Auth state
      onAuthStateChanged(auth, user => {
        if (user) {
          startRsvpButton.textContent = 'LOGOUT';
          // Show guestbook to logged-in users
          guestbookContainer.style.display = 'block';
    
          // Subscribe to the guestbook collection
          subscribeGuestbook();
          // Subcribe to the user's RSVP
          subscribeCurrentRSVP(user);
        } else {
          startRsvpButton.textContent = 'RSVP';
          // Hide guestbook for non-logged-in users
          guestbookContainer.style.display = 'none'
          ;
          // Unsubscribe from the guestbook collection
          unsubscribeGuestbook();
          // Unsubscribe from the guestbook collection
          unsubscribeCurrentRSVP();
        }
      });
    
  4. Tente fazer login como múltiplos usuários e ver o aumento contagem com cada botão SIM adicional clique.

Visualização do aplicativo

3df607d3e0b3c35.png

11. Parabéns!

Você usou o Firebase para criar um aplicativo da web interativo e em tempo real!

O que cobrimos

  • Firebase Authentication
  • FirebaseUI
  • Cloud Firestore
  • Regras de segurança do Firebase

Próximos passos

  • Quer saber mais sobre outros produtos Firebase? Talvez você queira armazenar arquivos de imagem que os usuários carregam? Ou enviar notificações para seus usuários? Confira o codelab web Firebase para uma codelab que entra em mais profundidade sobre muitos produtos mais Firebase para web.
  • Quer saber mais sobre o Cloud Firestore? Talvez você queira aprender sobre subcoleções e transações? De cabeça para o codelab web Nuvem Firestore para uma codelab que entra em mais profundidade sobre Nuvem Firestore. Ou confira esta série YouTube para conhecer Nuvem Firestore !

Saber mais

Como foi?

Adoraríamos receber seu feedback! Por favor, preencha um (muito) pequeno formulário aqui .