1. Co utworzysz
W tym ćwiczeniu z programowania utworzysz blog podróżniczy z mapą do współpracy w czasie rzeczywistym, korzystając z najnowszych funkcji naszej biblioteki Angular: AngularFire. Gotowa aplikacja internetowa będzie blogiem podróżniczym, na którym możesz przesyłać zdjęcia z każdego odwiedzonego miejsca.
Do tworzenia aplikacji internetowej użyjemy AngularFire, do testowania lokalnego – Pakietu emulatorów, do śledzenia danych użytkowników – Uwierzytelniania, do przechowywania danych i multimediów – Firestore i Storage (zasilanych przez Cloud Functions), a do wdrażania aplikacji – Hostingu Firebase.
Czego się nauczysz
- Jak lokalnie tworzyć aplikacje z użyciem usług Firebase za pomocą Pakietu emulatorów
- Jak ulepszyć aplikację internetową za pomocą AngularFire
- Jak utrwalać dane w Firestore
- Jak trwale przechowywać multimedia w usłudze Storage
- Jak wdrożyć aplikację w Hostingu Firebase
- Jak używać Cloud Functions do interakcji z bazami danych i interfejsami API
Czego potrzebujesz
- Node.js w wersji 10 lub nowszej
- konto Google do tworzenia projektu Firebase i zarządzania nim;
- Wiersz poleceń Firebase w wersji 11.14.2 lub nowszej
- wybraną przeglądarkę, np. Chrome;
- Podstawowa znajomość Angulara i JavaScriptu
2. Pobieranie przykładowego kodu
Sklonuj repozytorium GitHub z poziomu wiersza poleceń:
git clone https://github.com/firebase/codelab-friendlychat-web
Jeśli nie masz zainstalowanego narzędzia git, możesz pobrać repozytorium jako plik ZIP.
Repozytorium GitHub zawiera przykładowe projekty na różne platformy.
W tym laboratorium kodu używamy tylko repozytorium webframework:
- 📁 webframework: kod początkowy, na którym będziesz pracować w tym ćwiczeniu.
Instalowanie zależności
Po sklonowaniu zainstaluj zależności w folderze głównym i functions
przed skompilowaniem aplikacji internetowej.
cd webframework && npm install
cd functions && npm install
Zainstaluj wiersz poleceń Firebase
Zainstaluj wiersz poleceń Firebase, wpisując w terminalu to polecenie:
npm install -g firebase-tools
Sprawdź, czy wersja wiersza poleceń Firebase jest nowsza niż 11.14.2, używając tego polecenia:
firebase --version
Jeśli Twoja wersja jest starsza niż 11.14.2, zaktualizuj ją, wykonując te czynności:
npm update firebase-tools
3. Tworzenie i konfigurowanie projektu Firebase
Tworzenie projektu Firebase
- Zaloguj się w konsoli Firebase, korzystając ze swojego konta Google.
- Kliknij przycisk, aby utworzyć nowy projekt, a potem wpisz jego nazwę (np.
FriendlyChat
).
- 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.
Dodawanie aplikacji internetowej Firebase do projektu
- Kliknij ikonę internetu, aby utworzyć nową aplikację internetową Firebase.
- W następnym kroku zobaczysz obiekt konfiguracji. Skopiuj zawartość tego obiektu do pliku
environments/environment.ts
.
Konfigurowanie usług Firebase
Aplikacja, którą zamierzamy utworzyć, korzysta z usług Firebase dostępnych w przypadku aplikacji internetowych:
- Uwierzytelnianie Firebase, aby umożliwić użytkownikom łatwe logowanie się w aplikacji.
- Cloud Firestore – zapisywanie danych strukturalnych w chmurze i otrzymywanie natychmiastowych powiadomień o zmianach danych.
- Cloud Storage dla Firebase do zapisywania plików w chmurze.
- Hosting Firebase do hostowania i obsługi zasobów.
- Funkcje do interakcji z wewnętrznymi i zewnętrznymi interfejsami API.
Niektóre z tych usług wymagają specjalnej konfiguracji lub włączenia w konsoli Firebase.
Włącz logowanie przez Google w usłudze Uwierzytelnianie Firebase
Aby umożliwić użytkownikom logowanie się w aplikacji internetowej za pomocą kont Google, użyjemy metody logowania Google.
Aby włączyć logowanie się za pomocą Google:
- W konsoli Firebase w panelu po lewej stronie znajdź sekcję Kompilacja.
- Kliknij Uwierzytelnianie, a następnie kartę Metoda logowania (lub kliknij tutaj, aby przejść bezpośrednio do tej karty).
- Włącz dostawcę logowania Google, a następnie kliknij Zapisz.
- Ustaw publiczną nazwę aplikacji na <your-project-name> i wybierz adres e-mail pomocy dotyczącej projektu z menu.
Włącz Cloud Firestore
- W sekcji Kompilacja w konsoli Firebase kliknij Baza danych Firestore.
- W panelu Cloud Firestore kliknij Utwórz bazę danych.
- Ustaw lokalizację, w której będą przechowywane dane Cloud Firestore. Możesz pozostawić ustawienie domyślne lub wybrać region znajdujący się w pobliżu.
Włączanie Cloud Storage
Aplikacja internetowa używa Cloud Storage dla Firebase do przechowywania, przesyłania i udostępniania zdjęć.
- W sekcji Kompilacja w konsoli Firebase kliknij Storage.
- Jeśli nie widzisz przycisku Rozpocznij, oznacza to, że Cloud Storage jest już
jest włączona i nie musisz wykonywać czynności opisanych poniżej.
- Kliknij Rozpocznij.
- Przeczytaj wyłączenie odpowiedzialności dotyczące reguł zabezpieczeń projektu Firebase, a potem kliknij Dalej.
- Lokalizacja Cloud Storage jest wstępnie wybrana w tym samym regionie, który został wybrany dla bazy danych Cloud Firestore. Aby zakończyć konfigurację, kliknij Gotowe.
Domyślne reguły bezpieczeństwa zezwalają każdemu uwierzytelnionemu użytkownikowi na zapisywanie dowolnych danych w Cloud Storage. W dalszej części tego laboratorium kodowania zwiększymy bezpieczeństwo pamięci.
4. Łączenie z projektem Firebase
Interfejs wiersza poleceń Firebase umożliwia korzystanie z Hostingu Firebase do lokalnego udostępniania aplikacji internetowej, a także wdrażanie aplikacji internetowej w projekcie Firebase.
Sprawdź, czy wiersz poleceń ma dostęp do lokalnego katalogu webframework
aplikacji.
Połącz kod aplikacji internetowej z projektem Firebase. Najpierw zaloguj się w wierszu poleceń Firebase:
firebase login
Następnie uruchom to polecenie, aby utworzyć alias projektu. Zastąp $YOUR_PROJECT_ID
identyfikatorem projektu Firebase.
firebase use $YOUR_PROJECT_ID
Dodawanie AngularFire
Aby dodać AngularFire do aplikacji, uruchom to polecenie:
ng add @angular/fire
Następnie postępuj zgodnie z instrukcjami wiersza poleceń i wybierz funkcje, które są dostępne w Twoim projekcie Firebase.
Inicjowanie Firebase
Aby zainicjować projekt Firebase, uruchom to polecenie:
firebase init
Następnie, postępując zgodnie z instrukcjami w wierszu poleceń, wybierz funkcje i emulatory używane w projekcie Firebase.
Uruchamianie emulatorów
Z poziomu katalogu webframework
uruchom to polecenie, aby uruchomić emulatory:
firebase emulators:start
W końcu zobaczysz coś takiego:
$ firebase emulators:start
i emulators: Starting emulators: auth, functions, firestore, hosting, functions
i firestore: Firestore Emulator logging to firestore-debug.log
i hosting: Serving hosting files from: public
✔ hosting: Local server: http://localhost:5000
i ui: Emulator UI logging to ui-debug.log
i functions: Watching "/functions" for Cloud Functions...
✔ functions[updateMap]: firestore function initialized.
┌─────────────────────────────────────────────────────────────┐
│ ✔ All emulators ready! It is now safe to connect your app. │
│ i View Emulator UI at http://localhost:4000 │
└─────────────────────────────────────────────────────────────┘
┌────────────────┬────────────────┬─────────────────────────────────┐
│ Emulator │ Host:Port │ View in Emulator UI │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Authentication │ localhost:9099 │ http://localhost:4000/auth │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Functions │ localhost:5001 │ http://localhost:4000/functions │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Firestore │ localhost:8080 │ http://localhost:4000/firestore │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Hosting │ localhost:5000 │ n/a │
└────────────────┴────────────────┴─────────────────────────────────┘
Emulator Hub running at localhost:4400
Other reserved ports: 4500
Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.
Gdy zobaczysz komunikat ✔All emulators ready!
, emulatory będą gotowe do użycia.
Powinien pojawić się interfejs aplikacji podróżniczej, który (jeszcze!) nie działa:
Zaczynajmy!
5. Połącz aplikację internetową z emulatorami
Z tabeli w logach emulatora wynika, że emulator Cloud Firestore nasłuchuje na porcie 8080, a emulator uwierzytelniania na porcie 9099.
Otwieranie interfejsu EmulatorUI
W przeglądarce otwórz http://127.0.0.1:4000/. Powinien pojawić się interfejs Pakietu emulatorów.
Kierowanie aplikacji do korzystania z emulatorów
W pliku src/app/app.module.ts
dodaj ten kod do listy instrukcji importu w pliku AppModule
:
@NgModule({
declarations: [...],
imports: [
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideAuth(() => {
const auth = getAuth();
if (location.hostname === 'localhost') {
connectAuthEmulator(auth, 'http://127.0.0.1:9099', { disableWarnings: true });
}
return auth;
}),
provideFirestore(() => {
const firestore = getFirestore();
if (location.hostname === 'localhost') {
connectFirestoreEmulator(firestore, '127.0.0.1', 8080);
}
return firestore;
}),
provideFunctions(() => {
const functions = getFunctions();
if (location.hostname === 'localhost') {
connectFunctionsEmulator(functions, '127.0.0.1', 5001);
}
return functions;
}),
provideStorage(() => {
const storage = getStorage();
if (location.hostname === 'localhost') {
connectStorageEmulator(storage, '127.0.0.1', 5001);
}
return storage;
}),
...
]
Aplikacja jest teraz skonfigurowana do korzystania z lokalnych emulatorów, co umożliwia lokalne testowanie i programowanie.
6. Dodawanie uwierzytelniania
Teraz, gdy emulatory są skonfigurowane dla aplikacji, możemy dodać funkcje uwierzytelniania, aby mieć pewność, że każdy użytkownik jest zalogowany przed opublikowaniem wiadomości.
Aby to zrobić, możemy zaimportować funkcje signin
bezpośrednio z AngularFire i śledzić stan uwierzytelniania użytkownika za pomocą funkcji authState
. Zmodyfikuj funkcje strony logowania, aby przy wczytywaniu sprawdzała stan uwierzytelniania użytkownika.
Wstrzykiwanie uwierzytelniania AngularFire
W usłudze src/app/pages/login-page/login-page.component.ts
zaimportuj Auth
z usługi @angular/fire/auth
i wstaw go do LoginPageComponent
. Dostawców uwierzytelniania, takich jak Google, oraz funkcje, takie jaksignin
, signout
, można też bezpośrednio importować z tego samego pakietu i używać w aplikacji.
import { Auth, GoogleAuthProvider, signInWithPopup, signOut, user } from '@angular/fire/auth';
export class LoginPageComponent implements OnInit {
private auth: Auth = inject(Auth);
private provider = new GoogleAuthProvider();
user$ = user(this.auth);
constructor() {}
ngOnInit(): void {}
login() {
signInWithPopup(this.auth, this.provider).then((result) => {
const credential = GoogleAuthProvider.credentialFromResult(result);
return credential;
})
}
logout() {
signOut(this.auth).then(() => {
console.log('signed out');}).catch((error) => {
console.log('sign out error: ' + error);
})
}
}
Strona logowania jest już funkcjonalna. Spróbuj się zalogować i sprawdź wyniki w emulatorze uwierzytelniania.
7. Konfigurowanie Firestore
W tym kroku dodasz funkcję publikowania i aktualizowania postów na blogu podróżniczym przechowywanych w Firestore.
Podobnie jak w przypadku uwierzytelniania, funkcje Firestore są dostarczane w pakiecie z AngularFire. Każdy dokument należy do kolekcji i może mieć też kolekcje zagnieżdżone. Znajomość path
dokumentu w Firestore jest wymagana do tworzenia i aktualizowania postu na blogu podróżniczym.
Implementowanie usługi TravelService
W aplikacji internetowej wiele różnych stron będzie musiało odczytywać i aktualizować dokumenty Firestore, dlatego możemy zaimplementować funkcje w src/app/services/travel.service.ts
, aby uniknąć wielokrotnego wstrzykiwania tych samych funkcji AngularFire na każdej stronie.
Zacznij od wstrzyknięcia Auth
, podobnie jak w poprzednim kroku, a także Firestore
do naszej usługi. Przydatne jest też zdefiniowanie obiektu obserwowalnego user$
, który nasłuchuje bieżącego stanu uwierzytelniania.
import { doc, docData, DocumentReference, Firestore, getDoc, setDoc, updateDoc, collection, addDoc, deleteDoc, collectionData, Timestamp } from "@angular/fire/firestore";
export class TravelService {
firestore: Firestore = inject(Firestore);
auth: Auth = inject(Auth);
user$ = authState(this.auth).pipe(filter(user => user !== null), map(user => user!));
router: Router = inject(Router);
Dodawanie posta o podróży
Posty o podróżach będą przechowywane w Firestore jako dokumenty. Dokumenty muszą znajdować się w kolekcjach, więc kolekcja zawierająca wszystkie posty o podróżach będzie nosić nazwę travels
. Ścieżka każdego posta o tematyce podróżniczej będzie więc wyglądać tak: travels/
Za pomocą funkcji addDoc
z AngularFire można wstawić obiekt do kolekcji:
async addEmptyTravel(userId: String) {
...
addDoc(collection(this.firestore, 'travels'), travelData).then((travelRef) => {
collection(this.firestore, `travels/${travelRef.id}/stops`);
setDoc(travelRef, {... travelData, id: travelRef.id})
this.router.navigate(['edit', `${travelRef.id}`]);
return travelRef;
})
}
Aktualizowanie i usuwanie danych
Znając identyfikator UID dowolnego posta o podróżach, można wywnioskować ścieżkę dokumentu przechowywanego w Firestore, który można następnie odczytać, zaktualizować lub usunąć za pomocą funkcji updateFoc
i deleteDoc
AngularFire:
async updateData(path: string, data: Partial<Travel | Stop>) {
await updateDoc(doc(this.firestore, path), data)
}
async deleteData(path: string) {
const ref = doc(this.firestore, path);
await deleteDoc(ref)
}
Odczytywanie danych jako obiektu obserwowalnego
Posty z podróży i przystanki po drodze można modyfikować po utworzeniu, dlatego bardziej przydatne byłoby otrzymywanie obiektów dokumentów jako obiektów obserwowalnych, aby subskrybować wszelkie wprowadzane zmiany. Ta funkcja jest oferowana przez funkcje docData
i collectionData
z @angular/fire/firestore
.
getDocData(path: string) {
return docData(doc(this.firestore, path), {idField: 'id'}) as Observable<Travel | Stop>
}
getCollectionData(path: string) {
return collectionData(collection(this.firestore, path), {idField: 'id'}) as Observable<Travel[] | Stop[]>
}
Dodawanie przystanków do posta o podróży
Po skonfigurowaniu operacji na postach o podróżach czas pomyśleć o przystankach, które będą znajdować się w podkolekcji postu o podróżach, np. tak: travels/
Jest to niemal identyczne z tworzeniem posta o podróżach, więc spróbuj samodzielnie wdrożyć tę funkcję lub zapoznaj się z poniższym opisem:
async addStop(travelId: string) {
...
const ref = await addDoc(collection(this.firestore, `travels/${travelId}/stops`), stopData)
setDoc(ref, {...stopData, id: ref.id})
}
Świetnie! Funkcje Firestore zostały zaimplementowane w usłudze Travel, więc możesz teraz zobaczyć, jak działają.
Używanie funkcji Firestore w aplikacji
Otwórz src/app/pages/my-travels/my-travels.component.ts
i wstaw TravelService
, aby korzystać z jego funkcji.
travelService = inject(TravelService);
travelsData$: Observable<Travel[]>;
stopsList$!: Observable<Stop[]>;
constructor() {
this.travelsData$ = this.travelService.getCollectionData(`travels`) as Observable<Travel[]>
}
Metoda TravelService
jest wywoływana w konstruktorze, aby uzyskać tablicę Observable wszystkich podróży.
Jeśli potrzebne są tylko podróże bieżącego użytkownika, użyj query
funkcji.
Inne metody zapewniania bezpieczeństwa to wdrożenie reguł zabezpieczeń lub używanie Cloud Functions z Firestore, jak opisano w opcjonalnych krokach poniżej.
Następnie po prostu wywołaj funkcje zaimplementowane w TravelService
.
async createTravel(userId: String) {
this.travelService.addEmptyTravel(userId);
}
deleteTravel(travelId: String) {
this.travelService.deleteData(`travels/${travelId}`)
}
Strona Moje podróże powinna teraz działać. Sprawdź, co się dzieje w emulatorze Firestore, gdy tworzysz nowy post o podróżach.
Następnie powtórz te czynności w przypadku funkcji aktualizacji w /src/app/pages/edit-travels/edit-travels.component.ts
:
travelService: TravelService = inject(TravelService)
travelId = this.activatedRoute.snapshot.paramMap.get('travelId');
travelData$: Observable<Travel>;
stopsData$: Observable<Stop[]>;
constructor() {
this.travelData$ = this.travelService.getDocData(`travels/${this.travelId}`) as Observable<Travel>
this.stopsData$ = this.travelService.getCollectionData(`travels/${this.travelId}/stops`) as Observable<Stop[]>
}
updateCurrentTravel(travel: Partial<Travel>) {
this.travelService.updateData(`travels${this.travelId}`, travel)
}
updateCurrentStop(stop: Partial<Stop>) {
stop.type = stop.type?.toString();
this.travelService.updateData(`travels${this.travelId}/stops/${stop.id}`, stop)
}
addStop() {
if (!this.travelId) return;
this.travelService.addStop(this.travelId);
}
deleteStop(stopId: string) {
if (!this.travelId || !stopId) {
return;
}
this.travelService.deleteData(`travels${this.travelId}/stops/${stopId}`)
this.stopsData$ = this.travelService.getCollectionData(`travels${this.travelId}/stops`) as Observable<Stop[]>
}
8. Konfigurowanie pamięci
Teraz zaimplementujesz Storage, aby przechowywać obrazy i inne typy multimediów.
Cloud Firestore najlepiej nadaje się do przechowywania danych strukturalnych, takich jak obiekty JSON. Cloud Storage służy do przechowywania plików lub obiektów binarnych. W tej aplikacji użyjesz go, aby umożliwić użytkownikom udostępnianie zdjęć z podróży.
Podobnie jak w przypadku Firestore, przechowywanie i aktualizowanie plików w Storage wymaga unikalnego identyfikatora każdego pliku.
Zaimplementujmy funkcje w TraveService
:
Przesyłanie pliku
Otwórz src/app/services/travel.service.ts
i wstaw Storage z AngularFire:
export class TravelService {
firestore: Firestore = inject(Firestore);
auth: Auth = inject(Auth);
storage: Storage = inject(Storage);
Następnie zaimplementuj funkcję przesyłania:
async uploadToStorage(path: string, input: HTMLInputElement, contentType: any) {
if (!input.files) return null
const files: FileList = input.files;
for (let i = 0; i < files.length; i++) {
const file = files.item(i);
if (file) {
const imagePath = `${path}/${file.name}`
const storageRef = ref(this.storage, imagePath);
await uploadBytesResumable(storageRef, file, contentType);
return await getDownloadURL(storageRef);
}
}
return null;
}
Główna różnica między dostępem do dokumentów z Firestore a plików z Cloud Storage polega na tym, że chociaż oba typy danych mają ścieżki o strukturze folderów, kombinację adresu URL i ścieżki uzyskuje się za pomocą funkcji getDownloadURL
, którą można następnie zapisać i użyć w pliku
.
Korzystanie z funkcji w aplikacji
Przejdź do src/app/components/edit-stop/edit-stop.component.ts
i wywołaj funkcję przesyłania za pomocą tego kodu:
async uploadFile(file: HTMLInputElement, stop: Partial<Stop>) {
const path = `/travels/${this.travelId}/stops/${stop.id}`
const url = await this.travelService.uploadToStorage(path, file, {contentType: 'image/png'});
stop.image = url ? url : '';
this.travelService.updateData(path, stop);
}
Po przesłaniu obrazu sam plik multimedialny zostanie przesłany do pamięci, a jego adres URL zostanie odpowiednio zapisany w dokumencie w Firestore.
9. Wdrożenie aplikacji
Teraz możemy wdrożyć aplikację.
Skopiuj konfiguracje firebase
z src/environments/environment.ts
do src/environments/environment.prod.ts
i uruchom:
firebase deploy
Powinien pojawić się ekran podobny do tego:
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.
=== Deploying to 'friendly-travels-b6a4b'...
i deploying storage, firestore, hosting
i firebase.storage: checking storage.rules for compilation errors...
✔ firebase.storage: rules file storage.rules compiled successfully
i firestore: reading indexes from firestore.indexes.json...
i cloud.firestore: checking firestore.rules for compilation errors...
✔ cloud.firestore: rules file firestore.rules compiled successfully
i storage: latest version of storage.rules already up to date, skipping upload...
i firestore: deploying indexes...
i firestore: latest version of firestore.rules already up to date, skipping upload...
✔ firestore: deployed indexes in firestore.indexes.json successfully for (default) database
i hosting[friendly-travels-b6a4b]: beginning deploy...
i hosting[friendly-travels-b6a4b]: found 6 files in .firebase/friendly-travels-b6a4b/hosting
✔ hosting[friendly-travels-b6a4b]: file upload complete
✔ storage: released rules storage.rules to firebase.storage
✔ firestore: released rules firestore.rules to cloud.firestore
i hosting[friendly-travels-b6a4b]: finalizing version...
✔ hosting[friendly-travels-b6a4b]: version finalized
i hosting[friendly-travels-b6a4b]: releasing new version...
✔ hosting[friendly-travels-b6a4b]: release complete
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/friendly-travels-b6a4b/overview
Hosting URL: https://friendly-travels-b6a4b.web.app
10. Gratulacje!
Aplikacja powinna być teraz gotowa i wdrożona w Hostingu Firebase. Wszystkie dane i statystyki będą teraz dostępne w konsoli Firebase.
Aby poznać więcej funkcji AngularFire, Functions i reguł bezpieczeństwa, nie zapomnij zapoznać się z opcjonalnymi krokami poniżej oraz innymi samouczkami Firebase.
11. Opcjonalnie: strażnicy uwierzytelniania AngularFire
Oprócz uwierzytelniania Firebase AngularFire oferuje też ochronę tras na podstawie uwierzytelniania, dzięki czemu użytkownicy z niewystarczającym dostępem mogą być przekierowywani. Pomaga to chronić aplikację przed dostępem użytkowników do chronionych danych.
W src/app/app-routing.module.ts
zaimportuj
import {AuthGuard, redirectLoggedInTo, redirectUnauthorizedTo} from '@angular/fire/auth-guard'
Następnie możesz zdefiniować funkcje określające, kiedy i gdzie użytkownicy powinni być przekierowywani na określonych stronach:
const redirectUnauthorizedToLogin = () => redirectUnauthorizedTo(['signin']);
const redirectLoggedInToTravels = () => redirectLoggedInTo(['my-travels']);
Następnie po prostu dodaj je do tras:
const routes: Routes = [
{path: '', component: LoginPageComponent, canActivate: [AuthGuard], data: {authGuardPipe: redirectLoggedInToTravels}},
{path: 'signin', component: LoginPageComponent, canActivate: [AuthGuard], data: {authGuardPipe: redirectLoggedInToTravels}},
{path: 'my-travels', component: MyTravelsComponent, canActivate: [AuthGuard], data: {authGuardPipe: redirectUnauthorizedToLogin}},
{path: 'edit/:travelId', component: EditTravelsComponent, canActivate: [AuthGuard], data: {authGuardPipe: redirectUnauthorizedToLogin}},
];
12. Opcjonalnie: reguły zabezpieczeń
Zarówno Firestore, jak i Cloud Storage używają reguł zabezpieczeń (firestore.rules
i security.rules
odpowiednio) do egzekwowania zabezpieczeń i weryfikowania danych.
Obecnie dane Firestore i Storage mają otwarty dostęp do odczytu i zapisu, ale nie chcesz, aby ludzie zmieniali posty innych osób. Za pomocą reguł zabezpieczeń możesz ograniczyć dostęp do kolekcji i dokumentów.
Reguły Firestore
Aby zezwolić na wyświetlanie postów o podróżach tylko uwierzytelnionym użytkownikom, otwórz plik firestore.rules
i dodaj:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/travels {
allow read: if request.auth.uid != null;
allow write:
if request.auth.uid == request.resource.data.userId;
}
}
Reguły zabezpieczeń mogą też służyć do weryfikacji danych:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/posts {
allow read: if request.auth.uid != null;
allow write:
if request.auth.uid == request.resource.data.userId;
&& "author" in request.resource.data
&& "text" in request.resource.data
&& "timestamp" in request.resource.data;
}
}
Reguły przechowywania
Podobnie możemy używać reguł zabezpieczeń do egzekwowania dostępu do baz danych pamięci masowej w storage.rules
. Pamiętaj, że możemy też używać funkcji do bardziej złożonych sprawdzeń:
rules_version = '2';
function isImageBelowMaxSize(maxSizeMB) {
return request.resource.size < maxSizeMB * 1024 * 1024
&& request.resource.contentType.matches('image/.*');
}
service firebase.storage {
match /b/{bucket}/o {
match /{userId}/{postId}/{filename} {
allow write: if request.auth != null
&& request.auth.uid == userId && isImageBelowMaxSize(5);
allow read;
}
}
}