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.
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ć.
- Aby uzyskać kod początkowy, otwórz ten adres URL: https://stackblitz.com/edit/firebase-gtk-web-start
- U góry strony StackBlitz kliknij Fork (Rozwidlenie):
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.
- W StackBlitz otwórz plik
index.html
. - Znajdź ikony
event-details-container
idescription-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
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
- Zaloguj się w konsoli Firebase, korzystając ze swojego konta Google.
- Kliknij przycisk, aby utworzyć nowy projekt, a następnie wpisz jego nazwę (np.
Firebase-Web-Codelab
). - Kliknij Dalej.
- Po wyświetleniu monitu przeczytaj i zaakceptuj warunki usługi Firebase, a potem kliknij Dalej.
- (Opcjonalnie) Włącz w konsoli Firebase pomoc AI (nazywaną „Gemini w Firebase”).
- W tym samouczku nie potrzebujesz Google Analytics, więc wyłącz opcję Google Analytics.
- 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 Firebase i Firebase 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:
- 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.
- Wybierz kartę Metoda logowania (lub kliknij tutaj, aby przejść bezpośrednio do tej karty).
- W opcjach dostawcy kliknij E-mail/hasło, włącz przełącznik Włącz, a następnie kliknij Zapisz.
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:
- W panelu po lewej stronie konsoli Firebase rozwiń Kompilacja, a następnie wybierz Baza danych Firestore.
- Kliknij Utwórz bazę danych.
- W polu Identyfikator bazy danych pozostaw wartość
(default)
. - Wybierz lokalizację bazy danych i kliknij Dalej.
W przypadku prawdziwej aplikacji wybierz lokalizację, która jest blisko użytkowników. - 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. - 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
- Wróć do konsoli Firebase i otwórz stronę przeglądu projektu, klikając Przegląd projektu w lewym górnym rogu.
- Na środku strony przeglądu projektu kliknij ikonę internetu
, aby utworzyć nową aplikację internetową Firebase.
- Zarejestruj aplikację pod nazwą Web App.
- 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.
- Kliknij Zarejestruj aplikację.
- Skopiuj obiekt konfiguracji Firebase do schowka.
- Kliknij Przejdź do konsoli.Dodaj do aplikacji obiekt konfigurujący Firebase:
- Wróć do StackBlitz i otwórz plik
index.js
. - Znajdź wiersz komentarza
Add Firebase project configuration object here
, a następnie wklej fragment kodu konfiguracji tuż pod nim. - 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
- W StackBlitz otwórz plik
index.js
. - U góry znajdź instrukcję importu
firebase/auth
, a następnie dodajgetAuth
iEmailAuthProvider
, jak poniżej:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider } from 'firebase/auth'; import {} from 'firebase/firestore';
- Zapisz odwołanie do obiektu autoryzacji zaraz po
initializeApp
, w ten sposób:initializeApp(firebaseConfig); auth = getAuth();
- 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.
- Na dole funkcji
main()
w plikuindex.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
- W StackBlitz otwórz plik
index.html
. - 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ściid
, co poniżej, ponieważ w tym samouczku w plikuindex.js
są już zaczepy dla tych konkretnych identyfikatorów.
Zwróć uwagę, że w plikuindex.html
znajduje się kontener o identyfikatorzefirebaseui-auth-container
. Jest to identyfikator, który przekażesz do FirebaseUI, aby przechowywać dane logowania. Podgląd aplikacji<!-- ... --> <section id="event-details-container"> <!-- ... --> <!-- ADD THE RSVP BUTTON HERE --> <button id="startRsvp">RSVP</button> </section> <hr> <section id="firebaseui-auth-container"></section> <!-- ... -->
- 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 funkcjimain()
w plikuindex.js
:async function main() { // ... // Listen to RSVP button clicks startRsvpButton.addEventListener("click", () => { ui.start("#firebaseui-auth-container", uiConfig); }); } main();
Testowanie logowania w aplikacji
- 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
lubThe 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.
- 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.
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ę”.
- W StackBlitz otwórz plik
index.js
. - U góry znajdź instrukcję importu
firebase/auth
, a następnie dodajsignOut
ionAuthStateChanged
, 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';
- 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();
- 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
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
.
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:
- W StackBlitz otwórz plik
index.html
. - 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
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
.
- W StackBlitz otwórz plik
index.js
. - U góry znajdź instrukcję importowania
firebase/firestore
, a następnie dodajgetFirestore
,addDoc
icollection
, 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';
- Teraz zapiszemy odwołanie do obiektu Firestore
db
zaraz poinitializeApp
:initializeApp(firebaseConfig); auth = getAuth(); db = getFirestore();
- U dołu funkcji
main()
dodaj ten kod.
Pamiętaj, żeauth.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).
- W StackBlitz otwórz plik
index.js
. - 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
- Sprawdź, czy jesteś zalogowany(-a) w aplikacji.
- 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
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:
- W StackBlitz otwórz plik
index.html
. - W
guestbook-container
dodaj nową sekcję z identyfikatoremguestbook
.<!-- ... --> <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:
- W StackBlitz otwórz plik
index.js
. - U góry znajdź instrukcję importowania
firebase/firestore
, a następnie dodajquery
,orderBy
ionSnapshot
, jak poniżej:// ... import { getFirestore, addDoc, collection, query, orderBy, onSnapshot } from 'firebase/firestore';
- 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
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:
- 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).
- Powinny pojawić się te domyślne reguły zabezpieczeń z limitem czasu dostępu publicznego wynoszącym kilka tygodni od dzisiaj.
Identyfikowanie kolekcji
Najpierw określ kolekcje, w których aplikacja zapisuje dane.
- Usuń istniejący klauzuli
match /{document=**}
, aby reguły wyglądały tak:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { } }
- 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.
- 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; } } }
- 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
- 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; } } }
- 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.
- W StackBlitz otwórz plik
index.js
. - Przenieś odbiornik kolekcji księgi gości
onSnapshot
do nowej funkcji o nazwiesubscribeGuestbook
. Przypisz też wyniki funkcjionSnapshot
do zmiennejguestbookListener
.
onSnapshot
Detektorzwraca 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); }); }); }
- Dodaj pod nią nową funkcję o nazwie
unsubscribeGuestbook
. Sprawdź, czy zmiennaguestbookListener
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
.
- Dodaj
subscribeGuestbook()
u dołuif (user)
. - Dodaj
unsubscribeGuestbook()
na końcu stwierdzeniaelse
.// ... // 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.
- W StackBlitz otwórz plik
index.html
. - W sekcji
guestbook-container
dodaj zestaw przycisków TAK i NIE, 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
Następnie zarejestruj odbiornik kliknięć przycisku. Jeśli użytkownik kliknie TAK, użyj jego identyfikatora UID uwierzytelniania, aby zapisać odpowiedź w bazie danych.
- W StackBlitz otwórz plik
index.js
. - U góry znajdź instrukcję importowania
firebase/firestore
, a następnie dodajdoc
,setDoc
iwhere
, 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';
- 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();
- 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 natrue
lubfalse
w zależności od tego, który przycisk zostanie kliknięty.
Najpierw w przypadkursvpYes
: Następnie zrób to samo w przypadku// ... // 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); } };
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
.
- W przypadku kolekcji
attendees
, ponieważ jako nazwę dokumentu użyto identyfikatora UID uwierzytelniania, możesz go pobrać i sprawdzić, czyuid
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; } } }
- Aby wdrożyć nowe reguły, kliknij Opublikuj.
Dodawanie reguł weryfikacji
- 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; } } }
- 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.
- W StackBlitz otwórz plik
index.html
. - W sekcji
description-container
dodaj nowy element z identyfikatoremnumber-attending
.<!-- ... --> <section id="description-container"> <!-- ... --> <p id="number-attending"></p> </section> <!-- ... -->
Następnie zarejestruj odbiorcę w attendees
kolekcji i policz liczbę odpowiedzi YES:
- W StackBlitz otwórz plik
index.js
. - 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.
- Utwórz funkcję, która sprawdza, czy bieżący identyfikator UID uwierzytelniania ma wpis w kolekcji
attendees
, a następnie ustaw klasę przycisku naclicked
.// ... // 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'; } } }); }
- 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 = ''; }
- 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(); } });
- 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
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
- Chcesz dowiedzieć się więcej o procesie pracy dewelopera Firebase? Zapoznaj się z ćwiczeniem dotyczącym emulatora Firebase, aby dowiedzieć się, jak testować i uruchamiać aplikację w całości lokalnie.
- Chcesz dowiedzieć się więcej o innych usługach Firebase? Może chcesz przechowywać pliki obrazów przesyłane przez użytkowników? Czy chcesz wysyłać powiadomienia do użytkowników? Zapoznaj się z samouczkiem dotyczącym Firebase w internecie, aby dowiedzieć się więcej o wielu innych usługach Firebase dla internetu.
- Chcesz dowiedzieć się więcej o Cloud Firestore? Może chcesz dowiedzieć się więcej o kolekcjach podrzędnych i transakcjach? Więcej informacji o Cloud Firestore znajdziesz w samouczku internetowym dotyczącym Cloud Firestore. Możesz też obejrzeć tę serię filmów na YouTube, aby poznać Cloud Firestore.
Więcej informacji
- Witryna Firebase: firebase.google.com
- Kanał Firebase w YouTube
Jak poszło?
Chętnie poznamy Twoją opinię. Wypełnij (bardzo) krótki formularz tutaj.