Informacje o Firebase w przeglądarce

1. Przegląd

Z tego samouczka dowiesz się, jak korzystać z podstawowych funkcji Firebase do tworzenia interaktywnych aplikacji internetowych. Utworzysz aplikację do potwierdzania udziału w wydarzeniu i czat księgi gości, korzystając z kilku usług Firebase.

zrzut ekranu z tym krokiem,

Czego się nauczysz

  • Uwierzytelniaj użytkowników za pomocą Uwierzytelniania Firebase i FirebaseUI.
  • Synchronizuj dane za pomocą Cloud Firestore.
  • Napisz reguły zabezpieczeń Firebase, aby zabezpieczyć bazę danych.

Czego potrzebujesz

  • wybraną przeglądarkę, np. Chrome;
  • Dostęp do stackblitz.com (nie jest wymagane konto ani logowanie).
  • Konto Google, np. konto Gmail. Zalecamy użycie konta e-mail, którego używasz już na koncie GitHub. Dzięki temu możesz korzystać z zaawansowanych funkcji w StackBlitz.
  • przykładowy kod z codelabu; W następnym kroku dowiesz się, jak uzyskać kod.

2. Pobieranie kodu początkowego

W tym laboratorium kodowania utworzysz aplikację za pomocą StackBlitz, czyli edytora online, który ma zintegrowanych kilka procesów Firebase. Stackblitz nie wymaga instalacji oprogramowania ani specjalnego konta StackBlitz.

StackBlitz umożliwia udostępnianie projektów innym osobom. Inne osoby, które mają adres URL Twojego projektu StackBlitz, mogą zobaczyć Twój kod i utworzyć kopię projektu, ale nie mogą go edytować.

  1. Aby uzyskać kod początkowy, otwórz ten adres URL: https://stackblitz.com/edit/firebase-gtk-web-start
  2. U góry strony StackBlitz kliknij Fork (Rozwidlenie):

zrzut ekranu z tym krokiem,

Masz teraz kopię kodu początkowego jako własny projekt StackBlitz, który ma unikalną nazwę i unikalny adres URL. Wszystkie pliki i zmiany są zapisywane w tym projekcie StackBlitz.

3. Edytowanie informacji o wydarzeniu

Materiały początkowe do tego laboratorium kodu zapewniają pewną strukturę aplikacji internetowej, w tym kilka arkuszy stylów i kilka kontenerów HTML dla aplikacji. W dalszej części tego laboratorium kodu połączysz te kontenery z Firebase.

Na początek zapoznajmy się z interfejsem StackBlitz.

  1. W StackBlitz otwórz plik index.html.
  2. Znajdź ikony event-details-containerdescription-container, a potem spróbuj edytować szczegóły wydarzenia.

Podczas edytowania tekstu automatyczne ponowne wczytywanie strony w StackBlitz wyświetla nowe szczegóły wydarzenia. Fajnie, nie?

<!-- ... -->

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

<!-- ... -->

Podgląd aplikacji powinien wyglądać mniej więcej tak:

Podgląd aplikacji

zrzut ekranu z tym krokiem,

4. Tworzenie i konfigurowanie projektu Firebase

Wyświetlanie informacji o wydarzeniu jest przydatne dla gości, ale samo wyświetlanie wydarzeń nie jest zbyt użyteczne dla nikogo. Dodajmy do tej aplikacji dynamiczne funkcje. W tym celu musisz połączyć Firebase z aplikacją. Aby zacząć korzystać z Firebase, musisz utworzyć i skonfigurować projekt Firebase.

Tworzenie projektu Firebase

  1. Zaloguj się w konsoli Firebase, korzystając ze swojego konta Google.
  2. Kliknij przycisk, aby utworzyć nowy projekt, a następnie wpisz jego nazwę (np. Firebase-Web-Codelab).
  3. Kliknij Dalej.
  4. Po wyświetleniu monitu przeczytaj i zaakceptuj warunki usługi Firebase, a potem kliknij Dalej.
  5. (Opcjonalnie) Włącz w konsoli Firebase pomoc AI (nazywaną „Gemini w Firebase”).
  6. W tym samouczku nie potrzebujesz Google Analytics, więc wyłącz opcję Google Analytics.
  7. Kliknij Utwórz projekt, poczekaj, aż projekt zostanie udostępniony, a następnie kliknij Dalej.

Więcej informacji o projektach Firebase znajdziesz w artykule Projekty w Firebase.

Włączanie i konfigurowanie usług Firebase w konsoli

Tworzona przez Ciebie aplikacja korzysta z kilku usług Firebase dostępnych w przypadku aplikacji internetowych:

  • Uwierzytelnianie FirebaseFirebase UI, aby umożliwić użytkownikom łatwe logowanie się w aplikacji.
  • Cloud Firestore – zapisywanie danych strukturalnych w chmurze i otrzymywanie natychmiastowych powiadomień o zmianach danych.
  • Reguły zabezpieczeń Firebase, aby zabezpieczyć bazę danych.

Niektóre z tych usług wymagają specjalnej konfiguracji lub włączenia w konsoli Firebase.

Włączanie logowania przez e-mail w usłudze Uwierzytelnianie Firebase

Aby umożliwić użytkownikom logowanie się w aplikacji internetowej, w tym laboratorium użyjesz metody logowania E-mail/hasło:

  1. W panelu po lewej stronie w konsoli Firebase kliknij Kompilacja > Uwierzytelnianie. Następnie kliknij Rozpocznij. Otworzy się panel uwierzytelniania, w którym możesz wyświetlać zarejestrowanych użytkowników, konfigurować dostawców logowania i zarządzać ustawieniami.

    zrzut ekranu z tym krokiem,

  2. Wybierz kartę Metoda logowania (lub kliknij tutaj, aby przejść bezpośrednio do tej karty).

    zrzut ekranu z tym krokiem,

  3. W opcjach dostawcy kliknij E-mail/hasło, włącz przełącznik Włącz, a następnie kliknij Zapisz.

    zrzut ekranu z tym krokiem,

Konfigurowanie Cloud Firestore

Aplikacja internetowa używa Cloud Firestore do zapisywania i odbierania nowych wiadomości na czacie.

Aby skonfigurować Cloud Firestore w projekcie Firebase:

  1. W panelu po lewej stronie konsoli Firebase rozwiń Kompilacja, a następnie wybierz Baza danych Firestore.
  2. Kliknij Utwórz bazę danych.
  3. W polu Identyfikator bazy danych pozostaw wartość (default).
  4. Wybierz lokalizację bazy danych i kliknij Dalej.
    W przypadku prawdziwej aplikacji wybierz lokalizację, która jest blisko użytkowników.
  5. Kliknij Uruchom w trybie testowym. Przeczytaj wyłączenie odpowiedzialności dotyczące reguł bezpieczeństwa.
    W dalszej części tego laboratorium dodasz reguły bezpieczeństwa, aby zabezpieczyć swoje dane. Nierozpowszechniajani nie udostępniaj publicznie aplikacji bez dodania reguł bezpieczeństwa do bazy danych.
  6. Kliknij Utwórz.

5. Dodawanie i konfigurowanie Firebase

Po utworzeniu projektu Firebase i włączeniu niektórych usług musisz poinformować kod, że chcesz korzystać z Firebase, a także wskazać, którego projektu Firebase chcesz używać.

Dodawanie bibliotek Firebase

Aby aplikacja mogła korzystać z Firebase, musisz dodać do niej biblioteki Firebase. Możesz to zrobić na kilka sposobów, które opisano w dokumentacji Firebase. Możesz na przykład dodać biblioteki z sieci CDN Google lub zainstalować je lokalnie za pomocą npm, a następnie spakować w aplikacji, jeśli używasz Browserify.

StackBlitz zapewnia automatyczne łączenie w pakiety, więc możesz dodawać biblioteki Firebase za pomocą instrukcji importu. Będziesz używać modułowych wersji bibliotek (wersja 9), które pomagają zmniejszyć ogólny rozmiar strony internetowej dzięki procesowi zwanemu „tree shaking”. Więcej informacji o modułowych pakietach SDK znajdziesz w dokumentacji.

Do utworzenia tej aplikacji użyjesz bibliotek Uwierzytelnianie Firebase, FirebaseUI i Cloud Firestore. W tym samouczku na początku pliku index.js znajdują się już te instrukcje importowania. W miarę postępów będziemy importować więcej metod z poszczególnych bibliotek Firebase:

// 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';

Dodawanie aplikacji internetowej Firebase do projektu Firebase

  1. Wróć do konsoli Firebase i otwórz stronę przeglądu projektu, klikając Przegląd projektu w lewym górnym rogu.
  2. Na środku strony przeglądu projektu kliknij ikonę internetu ikona aplikacji internetowej,, aby utworzyć nową aplikację internetową Firebase.

    zrzut ekranu z tym krokiem,

  3. Zarejestruj aplikację pod nazwą Web App.
  4. W tym samouczku NIE zaznaczaj pola obok opcji Also set up Firebase Hosting for this app (Skonfiguruj też Hosting Firebase dla tej aplikacji). Na razie będziesz używać panelu podglądu StackBlitz.
  5. Kliknij Zarejestruj aplikację.

    zrzut ekranu z tym krokiem,

  6. Skopiuj obiekt konfiguracji Firebase do schowka.

    zrzut ekranu z tym krokiem,

  7. Kliknij Przejdź do konsoli.Dodaj do aplikacji obiekt konfigurujący Firebase:
  8. Wróć do StackBlitz i otwórz plik index.js.
  9. Znajdź wiersz komentarza Add Firebase project configuration object here, a następnie wklej fragment kodu konfiguracji tuż pod nim.
  10. Dodaj wywołanie funkcji initializeApp, aby skonfigurować Firebase za pomocą unikalnej konfiguracji projektu 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.firebasestorage.app",
      messagingSenderId: "random-unique-string",
      appId: "random-unique-string",
    };
    
    // Initialize Firebase
    initializeApp(firebaseConfig);
    

6. Dodawanie logowania użytkownika (odpowiedzi)

Po dodaniu Firebase do aplikacji możesz skonfigurować przycisk potwierdzenia uczestnictwa, który rejestruje osoby za pomocą Uwierzytelniania Firebase.

Uwierzytelnianie użytkowników za pomocą logowania przez e-mail i FirebaseUI

Musisz mieć przycisk odpowiedzi, który wyświetla użytkownikowi prośbę o zalogowanie się przy użyciu adresu e-mail. Możesz to zrobić, podłączając FirebaseUI do przycisku RSVP.FirebaseUI to biblioteka, która zapewnia gotowy interfejs użytkownika oparty na Firebase Auth.

FirebaseUI wymaga konfiguracji (opcje znajdziesz w dokumentacji), która wykonuje 2 czynności:

  • Informuje FirebaseUI, że chcesz użyć metody logowania E-mail/hasło.
  • Obsługuje wywołanie zwrotne w przypadku udanego logowania i zwraca wartość false, aby uniknąć przekierowania. Nie chcesz, aby strona się odświeżała, ponieważ tworzysz aplikację internetową jednostronicową.

Dodaj kod inicjujący Uwierzytelnianie FirebaseUI

  1. W StackBlitz otwórz plik index.js.
  2. U góry znajdź instrukcję importu firebase/auth, a następnie dodaj getAuth i EmailAuthProvider, jak poniżej:
    // ...
    // Add the Firebase products and methods that you want to use
    import { getAuth, EmailAuthProvider } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. Zapisz odwołanie do obiektu autoryzacji zaraz po initializeApp, w ten sposób:
    initializeApp(firebaseConfig);
    auth = getAuth();
    
  4. Zwróć uwagę, że konfiguracja FirebaseUI jest już dostępna w kodzie początkowym. Jest już skonfigurowana do korzystania z dostawcy uwierzytelniania za pomocą poczty e-mail.
  5. Na dole funkcji main() w pliku index.js dodaj instrukcję inicjalizacji FirebaseUI:
    async function main() {
      // ...
    
      // Initialize the FirebaseUI widget using Firebase
      const ui = new firebaseui.auth.AuthUI(auth);
    }
    main();
    
    

Dodawanie przycisku odpowiedzi do kodu HTML

  1. W StackBlitz otwórz plik index.html.
  2. Dodaj kod HTML przycisku Odpowiedz wewnątrz tagu event-details-container, jak pokazano w przykładzie poniżej.

     Uważaj, aby używać tych samych wartości id, co poniżej, ponieważ w tym samouczku w pliku index.js są już zaczepy dla tych konkretnych identyfikatorów.

     Zwróć uwagę, że w pliku index.html znajduje się kontener o identyfikatorze firebaseui-auth-container. Jest to identyfikator, który przekażesz do FirebaseUI, aby przechowywać dane logowania.
    <!-- ... -->
    
    <section id="event-details-container">
        <!-- ... -->
        <!-- ADD THE RSVP BUTTON HERE -->
        <button id="startRsvp">RSVP</button>
    </section>
    <hr>
    <section id="firebaseui-auth-container"></section>
    <!-- ... -->
    
    Podgląd aplikacji

    zrzut ekranu z tym krokiem,

  3. Skonfiguruj detektor przycisku RSVP i wywołaj funkcję startową FirebaseUI. Informuje to FirebaseUI, że chcesz wyświetlić okno logowania.

     Dodaj ten kod na końcu funkcji main() w pliku index.js:
    async function main() {
      // ...
    
      // Listen to RSVP button clicks
      startRsvpButton.addEventListener("click",
       () => {
            ui.start("#firebaseui-auth-container", uiConfig);
      });
    }
    main();
    

Testowanie logowania w aplikacji

  1. W oknie podglądu StackBlitz kliknij przycisk RSVP, aby zalogować się w aplikacji.
    • W tym samouczku możesz użyć dowolnego adresu e-mail, nawet fałszywego, ponieważ nie będziesz w nim konfigurować kroku weryfikacji adresu e-mail.
    • Jeśli zobaczysz komunikat o błędzie auth/operation-not-allowed lub The given sign-in provider is disabled for this Firebase project, sprawdź, czy w konsoli Firebase masz włączoną opcję E-mail/hasło jako dostawcę logowania.
    Podgląd aplikacji

    zrzut ekranu z tym krokiem,

  2. W konsoli Firebase otwórz panel uwierzytelniania. Na karcie Użytkownicy powinny być widoczne informacje o koncie, które zostały wpisane podczas logowania się w aplikacji.

    zrzut ekranu z tym krokiem,

Dodawanie stanu uwierzytelniania do interfejsu

Następnie sprawdź, czy interfejs użytkownika odzwierciedla fakt, że jesteś zalogowany(-a).

Użyjesz wywołania zwrotnego odbiornika stanu uwierzytelniania Firebase, które jest powiadamiane o każdej zmianie stanu logowania użytkownika. Jeśli użytkownik jest zalogowany, aplikacja zmieni przycisk „Potwierdź udział” na przycisk „Wyloguj się”.

  1. W StackBlitz otwórz plik index.js.
  2. U góry znajdź instrukcję importu firebase/auth, a następnie dodaj signOut i onAuthStateChanged, jak poniżej:
    // ...
    // Add the Firebase products and methods that you want to use
    import {
      getAuth,
      EmailAuthProvider,
      signOut,
      onAuthStateChanged
    } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. Na dole funkcji main() dodaj ten kod:
    async function main() {
      // ...
    
      // Listen to the current Auth state
      onAuthStateChanged(auth, user => {
        if (user) {
          startRsvpButton.textContent = 'LOGOUT';
        } else {
          startRsvpButton.textContent = 'RSVP';
        }
      });
    }
    main();
    
  4. W funkcji obsługi kliknięcia przycisku sprawdź, czy jest zalogowany bieżący użytkownik, i wyloguj go. Aby to zrobić, zastąp bieżący startRsvpButton.addEventListener tym kodem:
    // ...
    // 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);
      }
    });
    

Przycisk w aplikacji powinien teraz wyświetlać tekst WYLOGUJ SIĘ, a po kliknięciu powinien wrócić do tekstu ODPOWIEDZ.

Podgląd aplikacji

zrzut ekranu z tym krokiem,

7. Zapisywanie wiadomości w Cloud Firestore

Wiedza o tym, że użytkownicy przychodzą, jest świetna, ale dajmy gościom coś jeszcze do zrobienia w aplikacji. Co by było, gdyby mogli zostawiać wiadomości w księdze gości? Mogą napisać, dlaczego chcą wziąć udział w wydarzeniu lub kogo chcą spotkać.

Aby przechowywać wiadomości na czacie, które użytkownicy piszą w aplikacji, użyjesz Cloud Firestore.

Model danych

Cloud Firestore to baza danych NoSQL, a dane w niej przechowywane są podzielone na kolekcje, dokumenty, pola i podkolekcje. Każda wiadomość z czatu będzie przechowywana jako dokument w kolekcji najwyższego poziomu o nazwie guestbook.

Grafika modelu danych Firestore przedstawiająca kolekcję księgi gości z wieloma dokumentami wiadomości

Dodawanie wiadomości do Firestore

W tej sekcji dodasz funkcję, która umożliwi użytkownikom pisanie nowych wiadomości do bazy danych. Najpierw dodaj kod HTML elementów interfejsu (pola wiadomości i przycisku wysyłania). Następnie dodajesz kod, który łączy te elementy z bazą danych.

Aby dodać elementy interfejsu pola wiadomości i przycisku wysyłania:

  1. W StackBlitz otwórz plik index.html.
  2. Znajdź element guestbook-container, a następnie dodaj ten kod HTML, aby utworzyć formularz z polem wpisywania wiadomości i przyciskiem wysyłania.
    <!-- ... -->
    
     <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>
    
    <!-- ... -->
    

Podgląd aplikacji

zrzut ekranu z tym krokiem,

Kliknięcie przez użytkownika przycisku WYŚLIJ spowoduje uruchomienie poniższego fragmentu kodu. Spowoduje to dodanie zawartości pola wprowadzania wiadomości do kolekcji guestbook w bazie danych. W szczególności metoda addDoc dodaje treść wiadomości do nowego dokumentu (z automatycznie wygenerowanym identyfikatorem) w kolekcji guestbook.

  1. W StackBlitz otwórz plik index.js.
  2. U góry znajdź instrukcję importowania firebase/firestore, a następnie dodaj getFirestore, addDoc i collection, jak poniżej:
    // ...
    
    // 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. Teraz zapiszemy odwołanie do obiektu Firestore db zaraz po initializeApp:
    initializeApp(firebaseConfig);
    auth = getAuth();
    db = getFirestore();
    
  4. U dołu funkcji main() dodaj ten kod.

    Pamiętaj, że auth.currentUser.uid to odniesienie do automatycznie generowanego unikalnego identyfikatora, który usługa Uwierzytelnianie Firebase przypisuje wszystkim zalogowanym użytkownikom.
    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();
    

Wyświetlanie księgi gości tylko zalogowanym użytkownikom

Nie chcesz, aby czat gości był widoczny dla każdego. Aby zabezpieczyć czat, możesz zezwolić na wyświetlanie księgi gości tylko zalogowanym użytkownikom. W przypadku własnych aplikacji warto jednak zabezpieczyć bazę danych za pomocą reguł bezpieczeństwa Firebase. (Więcej informacji o regułach zabezpieczeń znajdziesz w dalszej części tego laboratorium).

  1. W StackBlitz otwórz plik index.js.
  2. Edytuj onAuthStateChanged, aby ukrywać i wyświetlać księgę gości.
    // ...
    
    // 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';
      }
    });
    

Testowanie wysyłania wiadomości

  1. Sprawdź, czy jesteś zalogowany(-a) w aplikacji.
  2. Wpisz wiadomość, np. „Cześć!”, a potem kliknij WYŚLIJ.

Ta czynność zapisuje wiadomość w bazie danych Cloud Firestore. Nie zobaczysz jednak jeszcze wiadomości w rzeczywistej aplikacji internetowej, ponieważ musisz jeszcze wdrożyć pobieranie danych. Zrobisz to w następnym kroku.

Możesz jednak zobaczyć nowo dodaną wiadomość w konsoli Firebase.

W panelu Baza danych Firestore w konsoli Firebase powinna być widoczna kolekcja guestbook z nowo dodaną wiadomością. Jeśli będziesz nadal wysyłać wiadomości, kolekcja księgi gości będzie zawierać wiele dokumentów, np. takich:

Konsola Firebase

zrzut ekranu z tym krokiem,

8. Czytanie wiadomości

Synchronizowanie wiadomości

To wspaniale, że goście mogą pisać wiadomości do bazy danych, ale nie mogą ich jeszcze zobaczyć w aplikacji.

Aby wyświetlać wiadomości, musisz dodać odbiorniki, które będą się uruchamiać, gdy dane ulegną zmianie, a potem utworzyć element interfejsu, który będzie wyświetlać nowe wiadomości.

Dodasz kod, który będzie nasłuchiwać nowo dodanych wiadomości z aplikacji. Najpierw dodaj w HTML-u sekcję, w której będą wyświetlane wiadomości:

  1. W StackBlitz otwórz plik index.html.
  2. guestbook-container dodaj nową sekcję z identyfikatorem guestbook.
    <!-- ... -->
    
      <section id="guestbook-container">
       <h2>Discussion</h2>
    
       <form><!-- ... --></form>
    
       <section id="guestbook"></section>
    
     </section>
    
    <!-- ... -->
    

Następnie zarejestruj odbiornik, który będzie nasłuchiwać zmian wprowadzanych w danych:

  1. W StackBlitz otwórz plik index.js.
  2. U góry znajdź instrukcję importowania firebase/firestore, a następnie dodaj query, orderBy i onSnapshot, jak poniżej:
    // ...
    import {
      getFirestore,
      addDoc,
      collection,
      query,
      orderBy,
      onSnapshot
    } from 'firebase/firestore';
    
  3. U dołu funkcji main() dodaj ten kod, aby przejść w pętli przez wszystkie dokumenty (wiadomości w księdze gości) w bazie danych. Aby dowiedzieć się więcej o tym, co się dzieje w tym kodzie, przeczytaj informacje pod fragmentem.
    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();
    

Aby odsłuchać wiadomości w bazie danych, utworzono zapytanie dotyczące konkretnej kolekcji za pomocą funkcji collection. Powyższy kod nasłuchuje zmian w kolekcji guestbook, w której są przechowywane wiadomości na czacie. Wiadomości są też uporządkowane według daty, a najnowsze są wyświetlane u góry – orderBy('timestamp', 'desc').

Funkcja onSnapshot przyjmuje 2 parametry: zapytanie do użycia i funkcję wywołania zwrotnego. Funkcja wywołania zwrotnego jest wywoływana, gdy w dokumentach pasujących do zapytania zostaną wprowadzone jakiekolwiek zmiany. Może to nastąpić, jeśli wiadomość zostanie usunięta, zmodyfikowana lub dodana. Więcej informacji znajdziesz w dokumentacji Cloud Firestore.

Testowanie synchronizacji wiadomości

Cloud Firestore automatycznie i natychmiast synchronizuje dane z klientami, którzy subskrybują bazę danych.

  • W aplikacji powinny być wyświetlane wiadomości utworzone wcześniej w bazie danych. Możesz napisać nowe wiadomości – powinny pojawić się od razu.
  • Jeśli otworzysz obszar roboczy w wielu oknach lub kartach, wiadomości będą synchronizowane w czasie rzeczywistym na wszystkich kartach.
  • (Opcjonalnie) Możesz spróbować ręcznie usunąć, zmodyfikować lub dodać nowe wiadomości bezpośrednio w sekcji Baza danych w konsoli Firebase. Wszelkie zmiany powinny być widoczne w interfejsie.

Gratulacje! Odczytujesz dokumenty Cloud Firestore w swojej aplikacji.

Podgląd aplikacji

zrzut ekranu z tym krokiem,

9. Konfigurowanie podstawowych reguł zabezpieczeń

Początkowo skonfigurowano Cloud Firestore do używania trybu testowego, co oznacza, że baza danych jest otwarta na odczyty i zapisy. Trybu testowego należy jednak używać tylko na bardzo wczesnych etapach tworzenia. Najlepiej jest skonfigurować reguły zabezpieczeń bazy danych podczas tworzenia aplikacji. Zabezpieczenia powinny być integralną częścią struktury i działania aplikacji.

Reguły zabezpieczeń umożliwiają kontrolowanie dostępu do dokumentów i kolekcji w bazie danych. Elastyczna składnia reguł umożliwia tworzenie reguł, które pasują do dowolnych operacji, od wszystkich zapisów w całej bazie danych po operacje na konkretnym dokumencie.

Reguły zabezpieczeń Cloud Firestore możesz pisać w konsoli Firebase:

  1. W sekcji Build (Kompilacja) w konsoli Firebase kliknij Firestore Database (Baza danych Firestore), a następnie wybierz kartę Rules (Reguły) lub kliknij tutaj, aby przejść bezpośrednio do karty Rules (Reguły).
  2. Powinny pojawić się te domyślne reguły zabezpieczeń z limitem czasu dostępu publicznego wynoszącym kilka tygodni od dzisiaj.

zrzut ekranu z tym krokiem,

Identyfikowanie kolekcji

Najpierw określ kolekcje, w których aplikacja zapisuje dane.

  1. Usuń istniejący klauzuli match /{document=**}, aby reguły wyglądały tak:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
      }
    }
    
  2. W sekcji match /databases/{database}/documents znajdź kolekcję, którą chcesz zabezpieczyć:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /guestbook/{entry} {
         // You'll add rules here in the next step.
      }
    }
    

Dodawanie reguł zabezpieczeń

Ponieważ w każdym dokumencie księgi gości używasz identyfikatora UID uwierzytelniania jako pola, możesz pobrać ten identyfikator i sprawdzić, czy każda osoba, która próbuje zapisać dane w dokumencie, ma pasujący identyfikator UID uwierzytelniania.

  1. Dodaj do zestawu reguł reguły odczytu i zapisu, jak pokazano poniżej:
    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;
        }
      }
    }
    
  2. Aby wdrożyć nowe reguły, kliknij Opublikuj.Od tej pory w księdze gości tylko zalogowani użytkownicy mogą czytać wiadomości (dowolne!), ale wiadomość możesz utworzyć tylko za pomocą swojego identyfikatora użytkownika. Nie zezwalamy też na edytowanie ani usuwanie wiadomości.

Dodawanie reguł weryfikacji

  1. Dodaj weryfikację danych, aby upewnić się, że w dokumencie znajdują się wszystkie oczekiwane pola:
    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;
        }
      }
    }
    
  2. Aby wdrożyć nowe reguły, kliknij Opublikuj.

Resetowanie detektorów

Ponieważ aplikacja umożliwia teraz logowanie tylko uwierzytelnionym użytkownikom, przenieś zapytanie firestore do księgi gości wewnątrz odbiornika uwierzytelniania. W przeciwnym razie wystąpią błędy uprawnień, a aplikacja zostanie odłączona, gdy użytkownik się wyloguje.

  1. W StackBlitz otwórz plik index.js.
  2. Przenieś odbiornik kolekcji księgi gości onSnapshot do nowej funkcji o nazwie subscribeGuestbook. Przypisz też wyniki funkcji onSnapshot do zmiennej guestbookListener.

     onSnapshotDetektorzwraca funkcję anulowania subskrypcji, której możesz później użyć do anulowania detektora migawek.
    // ...
    // 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);
        });
      });
    }
    
  3. Dodaj pod nią nową funkcję o nazwie unsubscribeGuestbook. Sprawdź, czy zmienna guestbookListener nie ma wartości null, a następnie wywołaj funkcję, aby anulować odbiornik.
    // ...
    // Unsubscribe from guestbook updates
    function unsubscribeGuestbook() {
      if (guestbookListener != null) {
        guestbookListener();
        guestbookListener = null;
      }
    }
    

Na koniec dodaj nowe funkcje do wywołania zwrotnego onAuthStateChanged.

  1. Dodaj subscribeGuestbook() u dołu if (user).
  2. Dodaj unsubscribeGuestbook() na końcu stwierdzenia else.
    // ...
    // 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. Krok dodatkowy: przećwicz zdobytą wiedzę

Rejestrowanie stanu odpowiedzi uczestnika

Obecnie Twoja aplikacja umożliwia rozpoczęcie czatu tylko wtedy, gdy użytkownik jest zainteresowany wydarzeniem. Jedynym sposobem, aby dowiedzieć się, czy ktoś przyjdzie, jest sprawdzenie, czy napisał o tym na czacie. Zorganizujmy się i poinformujmy innych, ile osób przyjdzie.

Dodasz przełącznik, aby rejestrować osoby, które chcą wziąć udział w wydarzeniu, a następnie zbierać informacje o liczbie uczestników.

  1. W StackBlitz otwórz plik index.html.
  2. W sekcji guestbook-container dodaj zestaw przycisków TAKNIE, np. w ten sposób:
    <!-- ... -->
      <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>
    <!-- ... -->
    

Podgląd aplikacji

zrzut ekranu z tym krokiem,

Następnie zarejestruj odbiornik kliknięć przycisku. Jeśli użytkownik kliknie TAK, użyj jego identyfikatora UID uwierzytelniania, aby zapisać odpowiedź w bazie danych.

  1. W StackBlitz otwórz plik index.js.
  2. U góry znajdź instrukcję importowania firebase/firestore, a następnie dodaj doc, setDoc i where, jak poniżej:
    // ...
    // 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. U dołu funkcji main() dodaj ten kod, aby nasłuchiwać stanu odpowiedzi:
    async function main() {
      // ...
    
      // Listen to RSVP responses
      rsvpYes.onclick = async () => {
      };
      rsvpNo.onclick = async () => {
      };
    }
    main();
    
    
  4. Następnie utwórz nową kolekcję o nazwie attendees, a potem zarejestruj odwołanie do dokumentu, jeśli klikniesz którykolwiek z przycisków RSVP. Ustaw ten odnośnik na true lub false w zależności od tego, który przycisk zostanie kliknięty.

     Najpierw w przypadku 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);
      }
    };
    
    Następnie zrób to samo w przypadku rsvpNo, ale z wartością 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);
      }
    };
    

Aktualizowanie reguł zabezpieczeń

Ponieważ masz już skonfigurowane reguły, nowe dane dodawane za pomocą przycisków zostaną odrzucone.

Zezwalaj na dodawanie elementów do kolekcji attendees

Musisz zaktualizować reguły, aby zezwolić na dodawanie do kolekcji attendees.

  1. W przypadku kolekcji attendees, ponieważ jako nazwę dokumentu użyto identyfikatora UID uwierzytelniania, możesz go pobrać i sprawdzić, czy uid osoby przesyłającej jest taki sam jak w dokumencie, który pisze. Zezwolisz wszystkim na odczytywanie listy uczestników (ponieważ nie zawiera ona danych prywatnych), ale tylko twórca będzie mógł ją aktualizować.
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        // ... //
        match /attendees/{userId} {
          allow read: if true;
          allow write: if request.auth.uid == userId;
        }
      }
    }
    
  2. Aby wdrożyć nowe reguły, kliknij Opublikuj.

Dodawanie reguł weryfikacji

  1. Dodaj reguły sprawdzania poprawności danych, aby mieć pewność, że w dokumencie znajdują się wszystkie oczekiwane pola:
    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;
    
        }
      }
    }
    
  2. Nie zapomnij kliknąć Opublikuj, aby wdrożyć reguły.

(Opcjonalnie) Możesz teraz wyświetlić wyniki kliknięcia przycisków. Otwórz panel Cloud Firestore w konsoli Firebase.

Odczytywanie stanu odpowiedzi

Po zarejestrowaniu odpowiedzi sprawdźmy, kto przyjdzie, i odzwierciedlmy to w interfejsie.

  1. W StackBlitz otwórz plik index.html.
  2. W sekcji description-container dodaj nowy element z identyfikatorem number-attending.
    <!-- ... -->
    
     <section id="description-container">
         <!-- ... -->
         <p id="number-attending"></p>
     </section>
    
    <!-- ... -->
    

Następnie zarejestruj odbiorcę w attendees kolekcji i policz liczbę odpowiedzi YES:

  1. W StackBlitz otwórz plik index.js.
  2. U dołu funkcji main() dodaj ten kod, aby nasłuchiwać stanu odpowiedzi i zliczać kliknięcia YES.
    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();
    

Na koniec wyróżnijmy przycisk odpowiadający bieżącemu stanowi.

  1. Utwórz funkcję, która sprawdza, czy bieżący identyfikator UID uwierzytelniania ma wpis w kolekcji attendees, a następnie ustaw klasę przycisku na 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. Utwórzmy też funkcję anulowania subskrypcji. Będzie on używany, gdy użytkownik się wyloguje.
    // ...
    function unsubscribeCurrentRSVP() {
      if (rsvpListener != null) {
        rsvpListener();
        rsvpListener = null;
      }
      rsvpYes.className = '';
      rsvpNo.className = '';
    }
    
  3. Wywołaj funkcje z odsłuchu Uwierzytelniania.
    // ...
    // 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();
          // Subscribe 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. Spróbuj zalogować się jako kilku użytkowników i sprawdź, czy liczba zwiększa się po każdym kliknięciu przycisku TAK.

Podgląd aplikacji

zrzut ekranu z tym krokiem,

11. Gratulacje!

Udało Ci się utworzyć interaktywną aplikację internetową działającą w czasie rzeczywistym za pomocą Firebase.

Omówione zagadnienia

  • Uwierzytelnianie Firebase
  • FirebaseUI
  • Cloud Firestore
  • Reguły zabezpieczeń Firebase

Dalsze kroki

Więcej informacji

Jak poszło?

Chętnie poznamy Twoją opinię. Wypełnij (bardzo) krótki formularz tutaj.