Poznaj Firebase dla Internetu

1. Przegląd

Podczas tych zajęć z programowania poznasz podstawy Firebase do tworzenia interaktywnych aplikacji internetowych. Stworzysz aplikację do odpowiedzi na wydarzenie i czatu w księdze gości, korzystając z kilku produktów Firebase.

zrzut ekranu przedstawiający ten krok

Czego się dowiesz

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

Co będziesz potrzebował

  • Wybrana przeglądarka, np. Chrome.
  • Dostęp do stackblitz.com (nie jest wymagane konto ani logowanie).
  • Konto Google, takie jak konto Gmail. Zalecamy konto e-mail, którego już używasz na swoim koncie GitHub. Dzięki temu możesz korzystać z zaawansowanych funkcji StackBlitz.
  • Przykładowy kod laboratorium programistycznego. Zobacz następny krok, aby dowiedzieć się, jak uzyskać kod.

2. Zdobądź kod startowy

Podczas tych zajęć z programowania będziesz budować aplikację za pomocą StackBlitz , edytora online, w którym zintegrowanych jest kilka przepływów pracy Firebase. Stackblitz nie wymaga instalacji oprogramowania ani specjalnego konta StackBlitz.

StackBlitz pozwala udostępniać projekty innym. Inne osoby posiadające adres URL Twojego projektu StackBlitz mogą zobaczyć Twój kod i rozwidlić Twój projekt, ale nie mogą edytować Twojego projektu StackBlitz.

  1. Przejdź do tego adresu URL, aby uzyskać kod początkowy: https://stackblitz.com/edit/firebase-gtk-web-start
  2. Na górze strony StackBlitz kliknij Widelec :

zrzut ekranu przedstawiający ten krok

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

3. Edytuj informacje o wydarzeniu

Materiały wyjściowe do tego ćwiczenia z kodowania zapewniają pewną strukturę aplikacji internetowej, w tym niektóre arkusze stylów i kilka kontenerów HTML dla aplikacji. W dalszej części tych zajęć z programowania podłączysz te kontenery do Firebase.

Na początek zapoznajmy się nieco z interfejsem StackBlitz.

  1. W StackBlitz otwórz plik index.html .
  2. Znajdź event-details-container i description-container , a następnie spróbuj edytować niektóre szczegóły wydarzenia.

Gdy edytujesz tekst, automatyczne przeładowanie strony w StackBlitz wyświetla szczegóły nowego wydarzenia. Super, tak?

<!-- ... -->

<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 Twojej aplikacji powinien wyglądać mniej więcej tak:

Podgląd aplikacji

zrzut ekranu przedstawiający ten krok

4. Utwórz i skonfiguruj projekt Firebase

Wyświetlanie informacji o wydarzeniu jest świetne dla gości, ale samo pokazywanie wydarzeń nie jest dla nikogo zbyt przydatne. Dodajmy do tej aplikacji dynamiczną funkcjonalność. W tym celu musisz podłączyć Firebase do swojej aplikacji. Aby rozpocząć korzystanie z Firebase, musisz utworzyć i skonfigurować projekt Firebase.

Utwórz projekt Firebase

  1. Zaloguj się do Firebase .
  2. W konsoli Firebase kliknij Dodaj projekt (lub Utwórz projekt ), a następnie nazwij swój projekt Firebase Firebase-Web-Codelab .

    zrzut ekranu przedstawiający ten krok

  3. Kliknij opcje tworzenia projektu. Jeśli pojawi się monit, zaakceptuj warunki Firebase. Na ekranie Google Analytics kliknij „Nie włączaj”, ponieważ nie będziesz używać Analytics w tej aplikacji.

Aby dowiedzieć się więcej o projektach Firebase, zobacz Omówienie projektów Firebase .

Włącz i skonfiguruj produkty Firebase w konsoli

Tworzona aplikacja korzysta z kilku produktów Firebase dostępnych dla aplikacji internetowych:

  • Uwierzytelnianie Firebase i interfejs Firebase , aby umożliwić użytkownikom łatwe logowanie się do Twojej aplikacji.
  • Cloud Firestore do zapisywania uporządkowanych danych w chmurze i otrzymywania natychmiastowych powiadomień o zmianach danych.
  • Reguły bezpieczeństwa Firebase zabezpieczające Twoją bazę danych.

Niektóre z tych produktów wymagają specjalnej konfiguracji lub wymagają włączenia za pomocą konsoli Firebase.

Włącz logowanie e-mailem dla uwierzytelniania Firebase

Aby umożliwić użytkownikom logowanie się do aplikacji internetowej, w tym ćwiczeniu z programowania użyjesz metody logowania za pomocą adresu e-mail/hasła :

  1. W lewym panelu konsoli Firebase kliknij Kompiluj > Uwierzytelnianie . Następnie kliknij Rozpocznij . Znajdujesz się teraz na pulpicie nawigacyjnym uwierzytelniania, gdzie możesz zobaczyć zarejestrowanych użytkowników, skonfigurować dostawców logowania i zarządzać ustawieniami.

    zrzut ekranu przedstawiający ten krok

  2. Wybierz zakładkę Metoda logowania (lub kliknij tutaj, aby przejść bezpośrednio do zakładki).

    zrzut ekranu przedstawiający ten krok

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

    zrzut ekranu przedstawiający ten krok

Skonfiguruj Cloud Firestore

Aplikacja internetowa korzysta z Cloud Firestore do zapisywania wiadomości czatu i odbierania nowych wiadomości czatu.

Oto jak skonfigurować Cloud Firestore:

  1. W lewym panelu konsoli Firebase kliknij Kompiluj > Baza danych Firestore . Następnie kliknij Utwórz bazę danych .
  2. Kliknij opcję Utwórz bazę danych .

    zrzut ekranu przedstawiający ten krok

  3. Wybierz opcję Uruchom w trybie testowym . Przeczytaj zastrzeżenie dotyczące zasad bezpieczeństwa. Tryb testowy zapewnia możliwość swobodnego zapisu do bazy danych podczas programowania. Kliknij Następny .

    zrzut ekranu przedstawiający ten krok

  4. Wybierz lokalizację swojej bazy danych (możesz po prostu użyć domyślnej). Pamiętaj jednak, że tej lokalizacji nie można później zmienić.

    zrzut ekranu przedstawiający ten krok

  5. Kliknij Gotowe .

5. Dodaj i skonfiguruj Firebase

Teraz, gdy masz już utworzony projekt Firebase i włączone niektóre usługi, musisz poinformować kod, że chcesz używać Firebase, a także którego projektu Firebase użyć.

Dodaj biblioteki Firebase

Aby Twoja aplikacja mogła korzystać z Firebase, musisz dodać do niej biblioteki Firebase. Można to zrobić na wiele sposobów, zgodnie z opisem w dokumentacji Firebase . Możesz na przykład dodać biblioteki z sieci CDN Google lub zainstalować je lokalnie przy użyciu npm, a następnie spakować je w swojej aplikacji, jeśli używasz przeglądarki Browserify.

StackBlitz zapewnia automatyczne łączenie, dzięki czemu możesz dodawać biblioteki Firebase za pomocą instrukcji importu. Będziesz używać modułowych (v9) wersji bibliotek, które pomagają zmniejszyć ogólny rozmiar strony internetowej poprzez proces zwany „wstrząsaniem drzewem”. Więcej informacji na temat modułowych zestawów SDK można znaleźć w dokumentacji .

Aby zbudować tę aplikację, korzystasz z bibliotek Firebase Authentication, FirebaseUI i Cloud Firestore. Na potrzeby tych zajęć z programowania następujące instrukcje importu znajdują się już na górze pliku index.js , a w miarę upływu czasu będziemy importować więcej metod z każdej biblioteki 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';

Dodaj aplikację internetową Firebase do swojego projektu Firebase

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

    zrzut ekranu przedstawiający ten krok

  3. Zarejestruj aplikację pod pseudonimem Web App .
  4. W przypadku tych zajęć z programowania NIE zaznaczaj pola obok Skonfiguruj także hosting Firebase dla tej aplikacji . Na razie będziesz korzystać z panelu podglądu StackBlitz.
  5. Kliknij opcję Zarejestruj aplikację .

    zrzut ekranu przedstawiający ten krok

  6. Skopiuj obiekt konfiguracyjny Firebase do schowka.

    zrzut ekranu przedstawiający ten krok

  7. Kliknij Kontynuuj, aby pocieszyć . Dodaj obiekt konfiguracyjny Firebase do swojej aplikacji:
  8. Wróć do StackBlitz i przejdź do pliku index.js .
  9. Znajdź Add Firebase project configuration object here , a następnie wklej fragment konfiguracji tuż pod komentarzem.
  10. Dodaj wywołanie initializeApp , aby skonfigurować Firebase przy użyciu 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.appspot.com",
      messagingSenderId: "random-unique-string",
      appId: "random-unique-string",
    };
    
    // Initialize Firebase
    initializeApp(firebaseConfig);
    

6. Dodaj logowanie użytkownika (RSVP)

Teraz, gdy dodałeś Firebase do aplikacji, możesz skonfigurować przycisk RSVP, który rejestruje osoby przy użyciu uwierzytelniania Firebase .

Uwierzytelnij swoich użytkowników za pomocą logowania e-mailowego i interfejsu FirebaseUI

Będziesz potrzebować przycisku odpowiedzi, który poprosi użytkownika 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 wstępnie zbudowany interfejs użytkownika na bazie Firebase Auth.

FirebaseUI wymaga konfiguracji (zobacz opcje w dokumentacji ), która wykonuje dwie rzeczy:

  • Informuje FirebaseUI, że chcesz używać metody logowania za pomocą adresu e-mail/hasła .
  • Obsługuje wywołanie zwrotne w celu pomyślnego logowania i zwraca wartość false, aby uniknąć przekierowania. Nie chcesz, aby strona była odświeżana, ponieważ tworzysz jednostronicową aplikację internetową.

Dodaj kod, aby zainicjować uwierzytelnianie FirebaseUI

  1. W StackBlitz przejdź do pliku index.js .
  2. Na górze znajdź instrukcję importu firebase/auth , a następnie dodaj getAuth i EmailAuthProvider , w ten sposób:
    // ...
    // Add the Firebase products and methods that you want to use
    import { getAuth, EmailAuthProvider } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. Zapisz odniesienie do obiektu auth zaraz po initializeApp , na przykład:
    initializeApp(firebaseConfig);
    auth = getAuth();
    
  4. Zwróć uwagę, że konfiguracja FirebaseUI jest już dostępna w kodzie początkowym. Jest już skonfigurowany do korzystania z dostawcy uwierzytelniania e-mail.
  5. Na dole funkcji main() w index.js dodaj instrukcję inicjującą FirebaseUI, na przykład:
    async function main() {
      // ...
    
      // Initialize the FirebaseUI widget using Firebase
      const ui = new firebaseui.auth.AuthUI(auth);
    }
    main();
    
    

Dodaj przycisk RSVP do kodu HTML

  1. W StackBlitz przejdź do pliku index.html .
  2. Dodaj kod HTML przycisku RSVP do event-details-container , jak pokazano w przykładzie poniżej.

    Uważaj, aby użyć tych samych wartości id , jak pokazano poniżej, ponieważ w przypadku tego ćwiczenia z programowania istnieją już zaczepy dla tych konkretnych identyfikatorów w pliku index.js .

    Zauważ, że w pliku index.html znajduje się kontener o identyfikatorze firebaseui-auth-container . Jest to identyfikator, który przekażesz do FirebaseUI w celu przechowywania Twojego loginu.
    <!-- ... -->
    
    <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 przedstawiający ten krok

  3. Skonfiguruj odbiornik na przycisku RSVP i wywołaj funkcję startową FirebaseUI. To informuje FirebaseUI, że chcesz zobaczyć okno logowania.

    Dodaj następujący kod na dole funkcji main() w index.js :
    async function main() {
      // ...
    
      // Listen to RSVP button clicks
      startRsvpButton.addEventListener("click",
       () => {
            ui.start("#firebaseui-auth-container", uiConfig);
      });
    }
    main();
    

Przetestuj logowanie do aplikacji

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

    zrzut ekranu przedstawiający ten krok

  2. Przejdź do panelu Uwierzytelnianie w konsoli Firebase. Na karcie Użytkownicy powinny pojawić się informacje o koncie wprowadzone w celu zalogowania się do aplikacji.

    zrzut ekranu przedstawiający ten krok

Dodaj stan uwierzytelniania do interfejsu użytkownika

Następnie upewnij się, że interfejs użytkownika odzwierciedla fakt, że jesteś zalogowany.

Będziesz używać wywołania zwrotnego nasłuchiwania stanu Firebase Authentication, które będzie powiadamiane za każdym razem, gdy zmieni się status logowania użytkownika. Jeśli aktualnie jest zalogowany użytkownik, Twoja aplikacja zmieni przycisk „Odpowiedz” na przycisk „Wyloguj”.

  1. W StackBlitz przejdź do pliku index.js .
  2. Na górze znajdź instrukcję importu firebase/auth , następnie dodaj signOut ' i onAuthStateChanged , w ten sposób:
    // ...
    // Add the Firebase products and methods that you want to use
    import {
      getAuth,
      EmailAuthProvider,
      signOut,
      onAuthStateChanged
    } from 'firebase/auth';
    
    import {} from 'firebase/firestore';
    
  3. Dodaj następujący kod na dole funkcji main() :
    async function main() {
      // ...
    
      // Listen to the current Auth state
      onAuthStateChanged(auth, user => {
        if (user) {
          startRsvpButton.textContent = 'LOGOUT';
        } else {
          startRsvpButton.textContent = 'RSVP';
        }
      });
    }
    main();
    
  4. W przycisku nasłuchiwania sprawdź, czy jest obecny użytkownik i wyloguj go. Aby to zrobić, zamień bieżący startRsvpButton.addEventListener na następujący:
    // ...
    // 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);
      }
    });
    

Teraz przycisk w Twojej aplikacji powinien wyświetlać komunikat WYLOGUJ i po kliknięciu powinien przełączyć się z powrotem na opcję RSVP .

Podgląd aplikacji

zrzut ekranu przedstawiający ten krok

7. Napisz wiadomości do Cloud Firestore

Świadomość, że użytkownicy przychodzą, jest świetna, ale dajmy gościom coś innego do zrobienia w aplikacji. A gdyby mogli zostawiać wiadomości w księdze gości? Mogą opowiedzieć, dlaczego tak bardzo chcą przyjechać lub kogo chcą spotkać.

Do przechowywania wiadomości czatu, które użytkownicy piszą w aplikacji, użyjesz Cloud Firestore .

Model danych

Cloud Firestore to baza danych NoSQL, a dane przechowywane w bazie danych są podzielone na kolekcje, dokumenty, pola i podkolekcje. Każdą wiadomość na czacie będziesz przechowywać jako dokument w kolekcji najwyższego poziomu zwanej guestbook .

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

Dodaj wiadomości do Firestore

W tej sekcji dodasz funkcję umożliwiającą użytkownikom zapisywanie nowych wiadomości w bazie danych. Najpierw dodajesz kod HTML elementów interfejsu użytkownika (pole wiadomości i przycisk wysyłania). Następnie dodajesz kod, który łączy te elementy z bazą danych.

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

  1. W StackBlitz przejdź do pliku index.html .
  2. Znajdź guestbook-container , a następnie dodaj następujący kod HTML, aby utworzyć formularz z polem do wprowadzania 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 przedstawiający ten krok

Użytkownik klikający przycisk WYŚLIJ uruchomi poniższy fragment kodu. Dodaje zawartość pola wejściowego wiadomości do zbioru guestbook w bazie danych. W szczególności metoda addDoc dodaje treść wiadomości do nowego dokumentu (z automatycznie wygenerowanym identyfikatorem) do kolekcji guestbook .

  1. W StackBlitz przejdź do pliku index.js .
  2. Na górze znajdź instrukcję importu firebase/firestore , a następnie dodaj getFirestore , addDoc i collection , w ten sposób:
    // ...
    
    // 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 db Firestore zaraz po initializeApp :
    initializeApp(firebaseConfig);
    auth = getAuth();
    db = getFirestore();
    
  4. Na dole funkcji main() dodaj następujący kod.

    Pamiętaj, że auth.currentUser.uid jest odniesieniem do automatycznie wygenerowanego unikalnego identyfikatora, który uwierzytelnianie Firebase zapewnia 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();
    

Pokaż księgę gości tylko zalogowanym użytkownikom

Nie chcesz, żeby ktokolwiek widział rozmowę gości. Jedną z rzeczy, które możesz zrobić, aby zabezpieczyć czat, jest zezwolenie na przeglądanie księgi gości tylko zalogowanym użytkownikom. To powiedziawszy, w przypadku własnych aplikacji będziesz chciał również zabezpieczyć swoją bazę danych za pomocą reguł bezpieczeństwa Firebase . (Więcej informacji na temat reguł bezpieczeństwa znajdziesz w dalszej części ćwiczeń z programowania).

  1. W StackBlitz przejdź do pliku index.js .
  2. Edytuj odbiornik onAuthStateChanged , aby ukryć i wyświetlić 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';
      }
    });
    

Testuj wysyłanie wiadomości

  1. Upewnij się, że jesteś zalogowany w aplikacji.
  2. Wpisz wiadomość, na przykład „Hej!”, a następnie kliknij WYŚLIJ .

Ta czynność zapisuje wiadomość w bazie danych Cloud Firestore. Jednak nie zobaczysz jeszcze tej wiadomości w swojej aplikacji internetowej, ponieważ nadal musisz zaimplementować pobieranie danych. Zrobisz to dalej.

Ale nowo dodaną wiadomość możesz zobaczyć w konsoli Firebase.

W konsoli Firebase, w panelu bazy danych Firestore , powinieneś zobaczyć kolekcję guestbook z nowo dodaną wiadomością. Jeśli będziesz nadal wysyłać wiadomości, Twoja księga gości będzie zawierać wiele dokumentów, takich jak ten:

Konsola Firebase

zrzut ekranu przedstawiający ten krok

8. Czytaj wiadomości

Synchronizuj wiadomości

Fajnie, że goście mogą zapisywać wiadomości do bazy danych, ale nie widzą ich jeszcze w aplikacji.

Aby wyświetlić wiadomości, musisz dodać detektory uruchamiające się po zmianie danych, a następnie utworzyć element interfejsu użytkownika, który będzie wyświetlał nowe wiadomości.

Dodasz kod, który nasłuchuje nowo dodanych wiadomości z aplikacji. Najpierw dodaj sekcję w kodzie HTML, aby wyświetlić wiadomości:

  1. W StackBlitz przejdź do pliku index.html .
  2. W 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 słuchacza, który nasłuchuje zmian wprowadzonych w danych:

  1. W StackBlitz przejdź do pliku index.js .
  2. Na górze znajdź instrukcję importu firebase/firestore , a następnie dodaj query , orderBy i onSnapshot , w ten sposób:
    // ...
    import {
      getFirestore,
      addDoc,
      collection,
      query,
      orderBy,
      onSnapshot
    } from 'firebase/firestore';
    
  3. Na dole funkcji main() dodaj następujący kod, aby przeglądać wszystkie dokumenty (wiadomości w księdze gości) w bazie danych. Aby dowiedzieć się więcej o tym, co dzieje się w tym kodzie, przeczytaj informacje poniżej fragmentu.
    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, utworzyłeś zapytanie dotyczące określonej kolekcji, korzystając z funkcji collection . Powyższy kod nasłuchuje zmian w kolekcji guestbook , w której przechowywane są wiadomości czatu. Wiadomości są również sortowane według daty, przy użyciu orderBy('timestamp', 'desc') , aby wyświetlić najnowsze wiadomości na górze.

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

Przetestuj synchronizację wiadomości

Cloud Firestore automatycznie i natychmiastowo synchronizuje dane z klientami zapisanymi do bazy danych.

  • W aplikacji powinny wyświetlić się wiadomości, które utworzyłeś wcześniej w bazie danych. Zapraszam do pisania nowych wiadomości; powinny pojawić się natychmiast.
  • Jeśli otworzysz obszar roboczy w wielu oknach lub kartach, wiadomości będą synchronizowane w czasie rzeczywistym na różnych kartach.
  • (Opcjonalnie) Możesz spróbować ręcznie usunąć, zmodyfikować lub dodać nowe wiadomości bezpośrednio w sekcji Baza danych konsoli Firebase; wszelkie zmiany powinny pojawić się w interfejsie użytkownika.

Gratulacje! Czytasz dokumenty Cloud Firestore w swojej aplikacji!

Podgląd aplikacji

zrzut ekranu przedstawiający ten krok

9. Skonfiguruj podstawowe reguły bezpieczeństwa

Początkowo skonfigurowałeś Cloud Firestore do korzystania z trybu testowego, co oznacza, że ​​Twoja baza danych jest otwarta do odczytu i zapisu. Jednakże trybu testowego należy używać tylko na bardzo wczesnych etapach programowania. Najlepszym rozwiązaniem jest skonfigurowanie reguł bezpieczeństwa dla bazy danych podczas tworzenia aplikacji. Bezpieczeństwo powinno być integralną częścią struktury i zachowania aplikacji.

Reguły Bezpieczeństwa pozwalają kontrolować dostęp do dokumentów i zbiorów znajdujących się w Twojej bazie danych. Elastyczna składnia reguł umożliwia tworzenie reguł pasujących do wszystkiego, od wszystkich zapisów do całej bazy danych po operacje na określonym dokumencie.

Możesz napisać reguły bezpieczeństwa dla Cloud Firestore w konsoli Firebase:

  1. W sekcji Kompilacja konsoli Firebase kliknij Baza danych Firestore , a następnie wybierz kartę Reguły (lub kliknij tutaj , aby przejść bezpośrednio do karty Reguły ).
  2. Powinieneś zobaczyć następujące domyślne reguły bezpieczeństwa, z limitem czasu publicznego dostępu za kilka tygodni od dzisiaj.

zrzut ekranu przedstawiający ten krok

Identyfikuj zbiory

Najpierw zidentyfikuj kolekcje, w których aplikacja zapisuje dane.

  1. Usuń istniejącą klauzulę match /{document=**} , aby Twoje reguły wyglądały tak:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
      }
    }
    
  2. W match /databases/{database}/documents zidentyfikuj 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.
      }
    }
    

Dodaj reguły bezpieczeństwa

Ponieważ użyłeś UID uwierzytelnienia jako pola w każdym dokumencie księgi gości, możesz uzyskać UID uwierzytelnienia i sprawdzić, czy każda osoba próbująca pisać do dokumentu ma pasujący UID uwierzytelnienia.

  1. Dodaj reguły odczytu i zapisu do zestawu reguł, 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. Kliknij Publikuj , aby wdrożyć nowe reguły. Teraz w przypadku księgi gości tylko zalogowani użytkownicy mogą czytać wiadomości (dowolne wiadomości!), ale możesz utworzyć wiadomość tylko przy użyciu swojego identyfikatora użytkownika. Nie zezwalamy również na edytowanie ani usuwanie wiadomości.

Dodaj reguły walidacji

  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. Kliknij Publikuj , aby wdrożyć nowe reguły.

Zresetuj słuchaczy

Ponieważ Twoja aplikacja umożliwia teraz logowanie się tylko uwierzytelnionym użytkownikom, powinieneś przenieść zapytanie księgi gości firestore do odbiornika uwierzytelniania. W przeciwnym razie wystąpią błędy uprawnień i aplikacja zostanie rozłączona po wylogowaniu się użytkownika.

  1. W StackBlitz przejdź do pliku index.js .
  2. Przeciągnij kolekcję księgi gości na odbiorniku onSnapshot do nowej funkcji o nazwie subscribeGuestbook . Przypisz także wyniki funkcji onSnapshot do zmiennej guestbookListener .

    Odbiornik Firestore onSnapshot zwraca funkcję anulowania subskrypcji, której będziesz mógł użyć do późniejszego anulowania odbiornika 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 spodem nową funkcję o nazwie unsubscribeGuestbook . Sprawdź, czy zmienna guestbookListener nie ma wartości null, a następnie wywołaj funkcję, aby anulować słuchacza.
    // ...
    // 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() na dole if (user) .
  2. Dodaj unsubscribeGuestbook() na dole instrukcji 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 to, czego się nauczyłeś

Zapisz status odpowiedzi uczestnika

W tej chwili Twoja aplikacja umożliwia ludziom rozpoczęcie czatu, jeśli są zainteresowani wydarzeniem. Poza tym jedynym sposobem, aby dowiedzieć się, czy ktoś przyjdzie, jest opublikowanie tej informacji na czacie. Zorganizujmy się i dajmy znać, ile osób przyjdzie.

Dodasz przełącznik umożliwiający rejestrację osób, które chcą wziąć udział w wydarzeniu, a następnie zbierzesz liczbę osób, które przyjdą.

  1. W StackBlitz przejdź do pliku index.html .
  2. W guestbook-container dodaj zestaw przycisków TAK i NIE , tak jak poniżej:
    <!-- ... -->
      <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 przedstawiający ten krok

Następnie zarejestruj słuchacza kliknięć przycisków. Jeśli użytkownik kliknie TAK , użyj swojego UID uwierzytelnienia, aby zapisać odpowiedź w bazie danych.

  1. W StackBlitz przejdź do pliku index.js .
  2. Na górze znajdź instrukcję importu firebase/firestore , następnie dodaj doc , setDoc i where , w ten sposób:
    // ...
    // 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 dole funkcji main() dodaj następujący kod, aby odsłuchać status 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 następnie zarejestruj odniesienie do dokumentu, jeśli zostanie kliknięty którykolwiek przycisk RSVP. Ustaw to odwołanie na true lub false w zależności od tego, który przycisk zostanie kliknięty.

    Najpierw dla 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 to samo dla 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);
      }
    };
    

Zaktualizuj swoje zasady bezpieczeństwa

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

Zezwalaj na dodatki do kolekcji attendees

Musisz zaktualizować reguły, aby umożliwić dodawanie do kolekcji attendees .

  1. W przypadku kolekcji attendees użyłeś identyfikatora UID uwierzytelnienia jako nazwy dokumentu, możesz go pobrać i sprawdzić, czy uid użytkownika przesyłającego jest taki sam jak dokument, który pisze. Zezwolisz każdemu na zapoznanie się z listą uczestników (ponieważ nie ma tam prywatnych danych), ale tylko twórca powinien mieć możliwość jej aktualizacji.
    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. Kliknij Publikuj , aby wdrożyć nowe reguły.

Dodaj reguły walidacji

  1. Dodaj reguły sprawdzania poprawności danych, aby upewnić się, ż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ć swoje reguły!

(Opcjonalnie) Możesz teraz wyświetlić wyniki kliknięcia przycisków. Przejdź do pulpitu nawigacyjnego Cloud Firestore w konsoli Firebase.

Przeczytaj status odpowiedzi

Teraz, gdy już nagrałeś odpowiedzi, zobaczmy, kto przyjdzie i odzwierciedlmy to w interfejsie użytkownika.

  1. W StackBlitz przejdź do pliku index.html .
  2. W description-container dodaj nowy element z identyfikatorem number-attending .
    <!-- ... -->
    
     <section id="description-container">
         <!-- ... -->
         <p id="number-attending"></p>
     </section>
    
    <!-- ... -->
    

Następnie zarejestruj słuchacza do kolekcji attendees i policz liczbę odpowiedzi TAK :

  1. W StackBlitz przejdź do pliku index.js .
  2. Na dole funkcji main() dodaj poniższy kod, aby odsłuchać status odpowiedzi i zliczyć kliknięcia TAK .
    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 podświetlmy przycisk odpowiadający aktualnemu statusowi.

  1. Utwórz funkcję sprawdzającą, czy bieżący identyfikator UID uwierzytelnienia 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. Stwórzmy także funkcję anulowania subskrypcji. Zostanie to wykorzystane, gdy użytkownik się wyloguje.
    // ...
    function unsubscribeCurrentRSVP() {
      if (rsvpListener != null) {
        rsvpListener();
        rsvpListener = null;
      }
      rsvpYes.className = '';
      rsvpNo.className = '';
    }
    
  3. Wywołaj funkcje z odbiornika 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 wielu użytkowników i zobacz, jak liczba użytkowników rośnie z każdym dodatkowym kliknięciem przycisku TAK .

Podgląd aplikacji

zrzut ekranu przedstawiający ten krok

11. Gratulacje!

Użyłeś Firebase do zbudowania interaktywnej aplikacji internetowej działającej w czasie rzeczywistym!

Co omówiliśmy

  • Uwierzytelnianie Firebase
  • FirebaseUI
  • Chmura Firestore
  • Reguły bezpieczeństwa Firebase

Następne kroki

Ucz się więcej

Jak poszło?

Będziemy wdzięczni za Twoją opinię! Proszę wypełnić (bardzo) krótki formularz tutaj .