1. Co utworzysz
W ramach tego ćwiczenia w programie utworzysz podróżniczego bloga, na którym możesz w czasie rzeczywistym współpracować nad mapą z najnowszymi informacjami z naszej biblioteki Angular: AngularFire. Końcowa aplikacja internetowa powstanie bloga podróżniczego, w którym możesz przesyłać zdjęcia do wszystkich odwiedzonych miejsc.
AngularFire będzie używany do tworzenia aplikacji internetowej, Pakietu emulatorów do testów lokalnych, uwierzytelniania do śledzenia danych użytkowników, Firestore i przechowywania danych do przechowywania danych i multimediów przy użyciu Cloud Functions, a na koniec do wdrożenia aplikacji w Hostingu Firebase.
Czego się nauczysz
- Jak programować lokalnie przy użyciu usług Firebase przy użyciu Pakietu emulatorów
- Jak ulepszyć aplikację internetową za pomocą AngularFire
- Jak zachować dane w Firestore
- Jak zachować multimedia w pamięci masowej
- 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 do zarządzania nim
- interfejs wiersza poleceń Firebase w wersji 11.14.2 lub nowszej.
- wybraną przeglądarkę, np. Chrome;
- Podstawowa znajomość języka Angular i JavaScriptu
2. Pobieranie przykładowego kodu
Skopiuj repozytorium GitHub ćwiczenia z programowania za pomocą wiersza poleceń:
git clone https://github.com/firebase/codelab-friendlychat-web
Jeśli nie masz zainstalowanej aplikacji git, możesz pobrać repozytorium jako plik ZIP.
Repozytorium GitHub zawiera przykładowe projekty na wiele platform.
To ćwiczenie w Codelabs korzysta tylko z repozytorium platformy internetowej:
- 📁 webframework: kod początkowy, który opracujesz w trakcie tego ćwiczenia z programowania.
Instalowanie zależności
Po sklonowaniu zainstaluj zależności w katalogu głównym i folderze functions
, zanim utworzysz aplikację internetową.
cd webframework && npm install
cd functions && npm install
Zainstaluj wiersz poleceń Firebase
Zainstaluj interfejs wiersza poleceń Firebase, używając tego polecenia w terminalu:
npm install -g firebase-tools
Dokładnie sprawdź, czy wersja wiersza poleceń Firebase jest w wersji nowszej niż 11.14.2 za pomocą:
firebase --version
Jeśli Twoja wersja jest starsza niż 11.14.2, zaktualizuj ją, używając:
npm update firebase-tools
3. Tworzenie i konfigurowanie projektu Firebase
Tworzenie projektu Firebase
- Zaloguj się w Firebase.
- W konsoli Firebase kliknij Dodaj projekt i nazwij projekt Firebase <Twój-projekt>. Zapamiętaj identyfikator projektu Firebase.
- Kliknij Utwórz projekt.
Ważne: projekt Firebase będzie miał nazwę <Twój-projekt>, ale Firebase automatycznie przypisze mu unikalny identyfikator w formacie <Twój-projekt>-1234. Ten unikalny identyfikator jest identyfikowany przez projekt (również w interfejsie wiersza poleceń), a <Twój-projekt> to po prostu wyświetlana nazwa.
Aplikacja, którą utworzymy, korzysta z usług Firebase dostępnych dla aplikacji internetowych:
- Uwierzytelnianie Firebase, które ułatwia użytkownikom logowanie się w Twojej aplikacji.
- Cloud Firestore pozwala zapisywać uporządkowane dane w chmurze i otrzymywać natychmiastowe powiadomienia o zmianach danych.
- Cloud Storage dla Firebase, aby zapisywać pliki w chmurze.
- Hosting Firebase do hostowania i wyświetlania zasobów.
- funkcje umożliwiające interakcję z wewnętrznymi i zewnętrznymi interfejsami API;
Niektóre z tych usług wymagają specjalnych konfiguracji lub trzeba włączyć je w konsoli Firebase.
Dodaj aplikację internetową Firebase do projektu
- Kliknij ikonę witryny, aby utworzyć nową aplikację internetową Firebase.
- W następnym kroku zobaczysz obiekt konfiguracji. Skopiuj zawartość tego obiektu do pliku
environments/environment.ts
.
włączyć logowanie się przez Google w Uwierzytelnianiu Firebase,
Aby umożliwić użytkownikom logowanie się w aplikacji internetowej za pomocą kont Google, użyjemy metody logowania Google.
Aby włączyć logowanie przez Google:
- W konsoli Firebase znajdź w panelu po lewej stronie sekcję Kompilacja.
- Kliknij Uwierzytelnianie, a następnie kartę Metoda logowania (lub kliknij tutaj, aby przejść bezpośrednio do tej sekcji).
- Włącz dostawcę logowania Google i kliknij Zapisz.
- Ustaw <nazwa-projektu> jako publiczną nazwę aplikacji i wybierz z menu Adres e-mail zespołu pomocy ds. projektu.
Włączanie Cloud Firestore
- W sekcji Tworzenie konsoli Firebase kliknij Baza danych Firestore.
- W panelu Cloud Firestore kliknij Utwórz bazę danych.
- Ustaw lokalizację przechowywania danych Cloud Firestore. Możesz pozostawić to ustawienie domyślne lub wybrać region w pobliżu.
Włącz Cloud Storage
Aplikacja internetowa korzysta z Cloud Storage dla Firebase do przechowywania, przesyłania i udostępniania zdjęć.
- W sekcji Kompilacja konsoli Firebase kliknij Miejsce na dane.
- Jeśli nie widzisz przycisku Rozpocznij, oznacza to, że usługa Cloud Storage jest już używana.
i nie musisz wykonywać czynności opisanych poniżej.
- Kliknij Rozpocznij.
- Przeczytaj wyłączenie odpowiedzialności dotyczące reguł zabezpieczeń projektu Firebase i kliknij Dalej.
- Wstępnie wybrana lokalizacja w Cloud Storage zawiera ten sam region, który został wybrany dla bazy danych Cloud Firestore. Kliknij Gotowe, aby zakończyć konfigurację.
Zgodnie z domyślnymi regułami zabezpieczeń każdy uwierzytelniony użytkownik może zapisywać w Cloud Storage dowolne informacje. W dalszej części tego ćwiczenia z programowania zwiększymy bezpieczeństwo naszego miejsca na dane.
4. Połącz z projektem Firebase
Interfejs wiersza poleceń Firebase (CLI) umożliwia korzystanie z Hostingu Firebase do lokalnego udostępniania aplikacji internetowej oraz wdrażania aplikacji internetowej w projekcie Firebase.
Upewnij się, że wiersz poleceń ma dostęp do lokalnego katalogu webframework
aplikacji.
Połącz kod aplikacji internetowej z projektem Firebase. Najpierw zaloguj się w interfejsie wiersza poleceń Firebase w wierszu poleceń:
firebase login
Następnie uruchom poniższe polecenie, aby utworzyć alias projektu. Zastąp $YOUR_PROJECT_ID
identyfikatorem projektu Firebase.
firebase use $YOUR_PROJECT_ID
Dodaj AngularFire
Aby dodać AngularFire do aplikacji, uruchom polecenie:
ng add @angular/fire
Następnie postępuj zgodnie z instrukcjami wiersza poleceń i wybierz funkcje dostępne w Twoim projekcie Firebase.
Zainicjuj Firebase
Aby zainicjować projekt Firebase, uruchom polecenie:
firebase init
Następnie, zgodnie z wierszami poleceń, wybierz funkcje i emulatory używane w Twoim projekcie Firebase.
Uruchom emulatory
W 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.
Zobaczysz interfejs aplikacji turystycznej, który jeszcze nie działa:
A teraz do roboty!
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 nasłuchuje na porcie 9099.
Otwórz EmulatorUI.
W przeglądarce otwórz stronę http://127.0.0.1:4000/. Powinien wyświetlić się interfejs użytkownika Pakietu emulatorów.
Kieruj aplikację, aby używać emulatorów
W programie src/app/app.module.ts
dodaj ten kod do listy importów usługi 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 używania lokalnych emulatorów, co umożliwia lokalne testowanie i programowanie.
6. Dodawanie uwierzytelniania
Po skonfigurowaniu emulatorów aplikacji możemy dodać funkcje uwierzytelniania, aby mieć pewność, że każdy użytkownik jest zalogowany przed opublikowaniem wiadomości.
W tym celu możemy zaimportować funkcje signin
bezpośrednio z AngularFire i śledzić stan uwierzytelniania użytkownika za pomocą funkcji authState
. Zmodyfikuj funkcje strony logowania, tak aby podczas jej wczytywania strona sprawdzała stan uwierzytelniania użytkownika.
Wstrzykiwanie uwierzytelniania AngularFire
W programie src/app/pages/login-page/login-page.component.ts
zaimportuj Auth
z usługi @angular/fire/auth
i wstrzyknij go w komponencie LoginPageComponent
. Dostawcy uwierzytelniania, tacy jak Google, i funkcje takie jak signin
, signout
również można zaimportować bezpośrednio z tego samego pakietu i użyć ich 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 już działa. Zaloguj się i sprawdź wyniki w emulatorze uwierzytelniania.
7. Konfigurowanie Firestore
W tym kroku dodasz funkcję publikowania i aktualizowania postów na blogach o podróżach przechowywanych w Firestore.
Podobnie jak uwierzytelnianie, funkcje Firestore są gotowe do użycia z AngularFire. Każdy dokument należy do kolekcji, a każdy dokument może też mieć kolekcje zagnieżdżone. Znajomość path
dokumentu w Firestore jest wymagana do utworzenia i zaktualizowania posta na blogu podróżniczego.
Wdrażanie usługi TravelService
Ponieważ wiele różnych stron będzie musiało odczytywać i aktualizować dokumenty Firestore w aplikacji internetowej, możemy wdrożyć te funkcje w zasadzie src/app/services/travel.service.ts
, aby uniknąć wielokrotnego wstrzykiwania tych samych funkcji AngularFire na każdej stronie.
Zacznij od wstrzykiwania Auth
, podobnie jak w poprzednim kroku, oraz Firestore
do naszej usługi. Warto też zdefiniować obserwowany obiekt 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 wpisu o podróży
Posty dotyczące podróży będą istnieć jako dokumenty przechowywane w Firestore, a ponieważ dokumenty muszą znajdować się w kolekcjach, kolekcja zawierająca wszystkie posty o podróżach będzie nosić nazwę travels
. Dlatego ścieżka każdego słupka podróżnego będzie mieć postać travels/
.
Za pomocą funkcji addDoc
z AngularFire możesz 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
Biorąc pod uwagę identyfikator UID dowolnego posta o podróży, można wywnioskować ścieżkę dokumentu zapisanego w Firestore, który następnie można 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 dostrzegalnych
Posty i przystanki na drodze można modyfikować po utworzeniu, więc lepiej byłoby pobrać obiekty dokumentu jako obiekty obserwacyjne, aby zasubskrybować wszelkie wprowadzane zmiany. Ta funkcja jest dostępna w ramach funkcji docData
i collectionData
z usługi @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>span>[]
}
Dodawanie przystanków do wpisu o podróży
Skoro działania związane z podróżą masz już skonfigurowane, czas pomyśleć o przystankach, które będą dostępne w podkolekcji poświęconej podróżowi: travels/
Działa to niemal tak samo jak tworzenie posta o podróży, więc musisz samodzielnie zaimplementować go lub sprawdzić to poniżej:
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 je teraz zobaczyć w akcji.
Korzystanie z funkcji Firestore w aplikacji
Przejdź do elementu src/app/pages/my-travels/my-travels.component.ts
i wstrzyknij TravelService
, aby używać jego funkcji.
travelService = inject(TravelService);
travelsData$: Observable<Travel[]>;
stopsList$!: Observable<Stop[]>;
constructor() {
this.travelsData$ = this.travelService.getCollectionData(`travels`) as Observable<Travel[]>
}
Funkcja TravelService
jest wywoływana w konstruktorze w celu uzyskania tablicy dostrzegalnej dla wszystkich podróży.
Jeśli potrzebna jest tylko podróż bieżącego użytkownika, użyj funkcji query
.
Inne metody zapewniania bezpieczeństwa to m.in. wdrożenie reguł zabezpieczeń lub używanie Cloud Functions z Firestore, co 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 już działać. Sprawdź, co się dzieje w emulatorze Firestore, gdy utworzysz nowy wpis o podróży.
Następnie powtórz te czynności w przypadku funkcji aktualizacji w komponencie /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 masowej
Teraz wdrożysz Cloud Storage, aby przechowywać obrazy i inne rodzaje multimediów.
Cloud Firestore najlepiej nadaje się do przechowywania uporządkowanych danych, takich jak obiekty JSON. Usługa Cloud Storage jest przeznaczona do przechowywania plików lub obiektów blob. W tej aplikacji umożliwisz użytkownikom udostępnianie zdjęć z podróży.
Podobnie w Firestore przechowywanie i aktualizowanie plików w pamięci masowej wymaga unikalnego identyfikatora każdego pliku.
Zaimplementujmy funkcje w komórce TraveService
:
Przesyłanie pliku
Przejdź do src/app/services/travel.service.ts
i wstrzyknij Storage z AngularFire:
export class TravelService {
firestore: Firestore = inject(Firestore);
auth: Auth = inject(Auth);
storage: Storage = inject(Storage);
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;
}
Podstawowa różnica między dostępem do dokumentów z Firestore a do plików z Cloud Storage polega na tym, że chociaż oba te procesy przebiegają według struktury folderów, jednak bazowa kombinacja adresu URL i ścieżki jest uzyskiwana za pomocą funkcji getDownloadURL
, którą można zapisać i wykorzystać w pliku .
Korzystanie z funkcji w aplikacji
Przejdź do src/app/components/edit-stop/edit-stop.component.ts
i wywołaj funkcję przesyłania, używając:
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 masowej, a URL zostanie zapisany odpowiednio w dokumencie w Firestore.
9. Wdrożenie aplikacji
Teraz możemy wdrożyć aplikację.
Skopiuj konfigurację 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!
Teraz aplikacja powinna być gotowa i wdrożona w Hostingu Firebase. Wszystkie dane i analizy będą teraz dostępne w konsoli Firebase.
Aby dowiedzieć się więcej o AngularFire, funkcjach i regułach zabezpieczeń, zapoznaj się z opcjonalnymi krokami poniżej oraz z innymi ćwiczeniami z programowania Firebase.
11. Opcjonalnie: zabezpieczenia uwierzytelniania AngularFire
Oprócz uwierzytelniania Firebase AngularFire oferuje też zabezpieczenia oparte na uwierzytelnianiu, dzięki czemu możliwe jest przekierowanie użytkowników z niewystarczającym dostępem. Pomaga to chronić aplikację przed użytkownikami uzyskującymi dostęp do danych chronionych.
Zaimportuj w src/app/app-routing.module.ts
import {AuthGuard, redirectLoggedInTo, redirectUnauthorizedTo} from '@angular/fire/auth-guard'
Następnie możesz zdefiniować funkcje określające, kiedy i gdzie użytkownicy mają być przekierowywani na określonych stronach:
const redirectUnauthorizedToLogin = () => redirectUnauthorizedTo(['signin']);
const redirectLoggedInToTravels = () => redirectLoggedInTo(['my-travels']);
Następnie po prostu dodaj je do swoich 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ń
Firestore i Cloud Storage używają reguł zabezpieczeń (odpowiednio firestore.rules
i security.rules
), aby egzekwować bezpieczeństwo i weryfikować dane.
W tej chwili dane Firestore i Storage mają otwarty dostęp do odczytu i zapisu, ale nie chcesz, aby użytkownicy zmieniali uprawnienia innych osób postów! Możesz użyć reguł zabezpieczeń, aby ograniczyć dostęp do kolekcji i dokumentów.
Reguły Firestore
Aby zezwolić tylko uwierzytelnionym użytkownikom na wyświetlanie postów o podróżach, 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 weryfikowania 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
W podobny sposób możemy wykorzystać reguły zabezpieczeń, aby wymusić dostęp do baz danych pamięci masowej w storage.rules
. Pamiętaj, że w przypadku bardziej złożonych testów możemy też użyć funkcji:
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;
}
}
}