Firebase Angular Web Frameworks Codelab

1. Was Sie erstellen werden

In diesem Codelab erstellen Sie einen Reiseblog mit einer kollaborativen Echtzeitkarte mit der neuesten Version unserer Angular-Bibliothek: AngularFire . Die fertige Web-App wird aus einem Reiseblog bestehen, in dem Sie Bilder zu jedem Ort hochladen können, zu dem Sie gereist sind.

AngularFire wird verwendet, um die Web-App zu erstellen, Emulator Suite für lokale Tests, Authentifizierung, um Benutzerdaten zu verfolgen, Firestore und Storage, um Daten und Medien beizubehalten, unterstützt durch Cloud Functions, und schließlich Firebase Hosting, um die App bereitzustellen.

Was Sie lernen werden

  • So entwickeln Sie Firebase-Produkte lokal mit der Emulator Suite
  • So verbessern Sie Ihre Web-App mit AngularFire
  • So behalten Sie Ihre Daten im Firestore bei
  • So behalten Sie Medien im Speicher bei
  • So stellen Sie Ihre App auf Firebase Hosting bereit
  • So verwenden Sie Cloud Functions für die Interaktion mit Ihren Datenbanken und APIs

Was du brauchen wirst

  • Node.js Version 10 oder höher
  • Ein Google-Konto für die Erstellung und Verwaltung Ihres Firebase-Projekts
  • Die Firebase CLI- Version 11.14.2 oder höher
  • Ein Browser Ihrer Wahl, z. B. Chrome
  • Grundkenntnisse von Angular und Javascript

2. Holen Sie sich den Beispielcode

Klonen Sie das GitHub-Repository des Codelab über die Befehlszeile:

git clone https://github.com/firebase/codelab-friendlychat-web

Alternativ können Sie, wenn Sie Git nicht installiert haben, das Repository als ZIP-Datei herunterladen .

Das Github-Repository enthält Beispielprojekte für mehrere Plattformen.

Dieses Codelab verwendet nur das Webframework-Repository:

  • 📁 Webframework : Der Startcode, auf dem Sie in diesem Codelab aufbauen.

Abhängigkeiten installieren

Installieren Sie nach dem Klonen die Abhängigkeiten im Stamm- und functions , bevor Sie die Web-App erstellen.

cd webframework && npm install
cd functions && npm install

Installieren Sie die Firebase-CLI

Installieren Sie Firebase CLI mit diesem Befehl in einem Terminal:

npm install -g firebase-tools

Überprüfen Sie noch einmal, ob Ihre Firebase-CLI-Version größer als 11.14.2 ist, indem Sie Folgendes verwenden:

firebase  --version

Wenn Ihre Version niedriger als 11.14.2 ist, aktualisieren Sie bitte mit:

npm update firebase-tools

3. Erstellen und richten Sie ein Firebase-Projekt ein

Erstellen Sie ein Firebase-Projekt

  1. Melden Sie sich bei Firebase an.
  2. Klicken Sie in der Firebase-Konsole auf Projekt hinzufügen und benennen Sie dann Ihr Firebase-Projekt <your-project> . Merken Sie sich die Projekt-ID für Ihr Firebase-Projekt.
  3. Klicken Sie auf Projekt erstellen .

Wichtig : Ihr Firebase-Projekt erhält den Namen <your-project> , aber Firebase weist ihm automatisch eine eindeutige Projekt-ID in der Form <your-project>-1234 zu. Mit dieser eindeutigen Kennung wird Ihr Projekt tatsächlich identifiziert (auch in der CLI), wohingegen <your-project> einfach ein Anzeigename ist.

Die Anwendung, die wir erstellen werden, verwendet Firebase-Produkte, die für Web-Apps verfügbar sind:

  • Firebase-Authentifizierung , um Ihren Benutzern die einfache Anmeldung bei Ihrer App zu ermöglichen.
  • Cloud Firestore , um strukturierte Daten in der Cloud zu speichern und sofortige Benachrichtigungen zu erhalten, wenn sich Daten ändern.
  • Cloud Storage für Firebase zum Speichern von Dateien in der Cloud.
  • Firebase Hosting zum Hosten und Bereitstellen Ihrer Assets.
  • Funktionen zur Interaktion mit internen und externen APIs.

Einige dieser Produkte erfordern spezielle Konfigurationen oder müssen über die Firebase-Konsole aktiviert werden.

Fügen Sie dem Projekt eine Firebase-Webanwendung hinzu

  1. Klicken Sie auf das Websymbol, um eine neue Firebase-Webanwendung zu erstellen.
  2. Im nächsten Schritt sehen Sie ein Konfigurationsobjekt. Kopieren Sie den Inhalt dieses Objekts in die Datei environments/environment.ts .

Aktivieren Sie die Google- Anmeldung für die Firebase-Authentifizierung

Damit sich Benutzer mit ihren Google-Konten bei der Web-App anmelden können, verwenden wir die Google- Anmeldemethode.

So aktivieren Sie die Google- Anmeldung:

  1. Suchen Sie in der Firebase-Konsole im linken Bereich den Abschnitt „Build“ .
  2. Klicken Sie auf Authentifizierung und dann auf die Registerkarte Anmeldemethode (oder klicken Sie hier , um direkt dorthin zu gelangen).
  3. Aktivieren Sie den Google -Anmeldeanbieter und klicken Sie dann auf Speichern .
  4. Legen Sie den öffentlich zugänglichen Namen Ihrer App auf <Ihr-Projektname> fest und wählen Sie im Dropdown-Menü eine E-Mail-Adresse für den Projektsupport aus.

Aktivieren Sie Cloud Firestore

  1. Klicken Sie im Abschnitt „Erstellen“ der Firebase-Konsole auf „Firestore-Datenbank“ .
  2. Klicken Sie im Cloud Firestore-Bereich auf Datenbank erstellen .
  3. Legen Sie den Speicherort fest, an dem Ihre Cloud Firestore-Daten gespeichert werden. Sie können dies als Standard belassen oder eine Region in Ihrer Nähe auswählen.

Aktivieren Sie Cloud-Speicher

Die Web-App nutzt Cloud Storage für Firebase zum Speichern, Hochladen und Teilen von Bildern.

  1. Klicken Sie im Build- Bereich der Firebase-Konsole auf Storage .
  2. Wenn es keine Schaltfläche „Erste Schritte“ gibt, bedeutet dies, dass der Cloud-Speicher bereits vorhanden ist

aktiviert und Sie müssen die folgenden Schritte nicht ausführen.

  1. Klicken Sie auf „Erste Schritte“ .
  2. Lesen Sie den Haftungsausschluss zu den Sicherheitsregeln für Ihr Firebase-Projekt und klicken Sie dann auf Weiter .
  3. Der Cloud-Speicherort ist mit derselben Region vorausgewählt, die Sie für Ihre Cloud Firestore-Datenbank ausgewählt haben. Klicken Sie auf Fertig, um die Einrichtung abzuschließen.

Mit den Standardsicherheitsregeln kann jeder authentifizierte Benutzer alles in Cloud Storage schreiben. Wir werden unseren Speicher später in diesem Codelab sicherer machen.

4. Stellen Sie eine Verbindung zu Ihrem Firebase-Projekt her

Mit der Firebase-Befehlszeilenschnittstelle (CLI) können Sie Firebase Hosting verwenden, um Ihre Web-App lokal bereitzustellen und Ihre Web-App in Ihrem Firebase-Projekt bereitzustellen.

Stellen Sie sicher, dass Ihre Befehlszeile auf das lokale webframework Verzeichnis Ihrer App zugreift.

Verbinden Sie den Web-App-Code mit Ihrem Firebase-Projekt. Melden Sie sich zunächst über die Befehlszeile bei der Firebase-CLI an:

firebase login

Führen Sie als Nächstes den folgenden Befehl aus, um einen Projektalias zu erstellen. Ersetzen Sie $YOUR_PROJECT_ID durch die ID Ihres Firebase-Projekts.

firebase  use  $YOUR_PROJECT_ID

AngularFire hinzufügen

Um AngularFire zur App hinzuzufügen, führen Sie den folgenden Befehl aus:

ng add @angular/fire

Befolgen Sie dann die Befehlszeilenanweisungen und wählen Sie die Funktionen aus, die in Ihrem Firebase-Projekt vorhanden sind.

Firebase initialisieren

Führen Sie Folgendes aus, um das Firebase-Projekt zu initialisieren:

firebase init

Befolgen Sie dann die Eingabeaufforderungen in der Befehlszeile und wählen Sie die Funktionen und Emulatoren aus, die in Ihrem Firebase-Projekt verwendet wurden.

Starten Sie die Emulatoren

Führen Sie im webframework Verzeichnis den folgenden Befehl aus, um die Emulatoren zu starten:

firebase  emulators:start

Irgendwann sollten Sie so etwas sehen:

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

Sobald Sie das ✔All emulators ready! Nachricht, die Emulatoren sind einsatzbereit.

Sie sollten die Benutzeroberfläche Ihrer Reise-App sehen, die (noch!) nicht funktioniert:

Jetzt lasst uns mit dem Bauen beginnen!

5. Verbinden Sie die Web-App mit den Emulatoren

Basierend auf der Tabelle in den Emulatorprotokollen überwacht der Cloud Firestore-Emulator Port 8080 und der Authentifizierungsemulator Port 9099.

Öffnen Sie die EmulatorUI

Navigieren Sie in Ihrem Webbrowser zu http://127.0.0.1:4000/ . Sie sollten die Benutzeroberfläche der Emulator Suite sehen.

Leiten Sie die App weiter, um die Emulatoren zu verwenden

Fügen Sie in src/app/app.module.ts den folgenden Code zur Importliste von AppModule hinzu:

@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;
		}),
		...
	]

Die App ist jetzt für die Verwendung lokaler Emulatoren konfiguriert, sodass Tests und Entwicklung lokal durchgeführt werden können.

6. Authentifizierung hinzufügen

Nachdem nun Emulatoren für die App eingerichtet sind, können wir Authentifizierungsfunktionen hinzufügen, um sicherzustellen, dass jeder Benutzer angemeldet ist, bevor er Nachrichten postet.

Dazu können wir signin direkt aus AngularFire importieren und den Authentifizierungsstatus Ihres Benutzers mit der Funktion authState verfolgen. Ändern Sie die Funktionen der Anmeldeseite so, dass die Seite beim Laden den Benutzerauthentifizierungsstatus überprüft.

AngularFire-Auth. einschleusen

Importieren Sie in src/app/pages/login-page/login-page.component.ts Auth aus @angular/fire/auth und fügen Sie es in die LoginPageComponent ein. Authentifizierungsanbieter wie Google und Funktionen wie signin und signout können ebenfalls direkt aus demselben Paket importiert und in der App verwendet werden.

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);
		})
	}
}

Jetzt ist die Anmeldeseite funktionsfähig! Versuchen Sie, sich anzumelden, und sehen Sie sich die Ergebnisse im Authentifizierungsemulator an.

7. Firestore konfigurieren

In diesem Schritt fügen Sie Funktionen zum Posten und Aktualisieren von im Firestore gespeicherten Reiseblogbeiträgen hinzu.

Ähnlich wie bei der Authentifizierung sind Firestore-Funktionen von AngularFire vorgefertigt. Jedes Dokument gehört zu einer Sammlung und jedes Dokument kann auch verschachtelte Sammlungen haben. Um einen Reiseblogbeitrag zu erstellen und zu aktualisieren, ist es erforderlich, den path des Dokuments in Firestore zu kennen.

Implementierung von TravelService

Da viele verschiedene Seiten Firestore-Dokumente in der Web-App lesen und aktualisieren müssen, können wir die Funktionen in src/app/services/travel.service.ts implementieren, um zu vermeiden, dass auf jeder Seite wiederholt dieselben AngularFire-Funktionen eingefügt werden.

Beginnen Sie mit der Einbindung Auth , ähnlich wie im vorherigen Schritt, sowie Firestore in unseren Dienst. Es ist auch nützlich, ein beobachtbares user$ zu definieren, das den aktuellen Authentifizierungsstatus überwacht.

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

Einen Reisebeitrag hinzufügen

Reisebeiträge werden als Dokumente vorliegen, die in Firestore gespeichert werden. Da Dokumente in Sammlungen vorhanden sein müssen, wird die Sammlung, die alle Reisebeiträge enthält, travels genannt. Somit wird der Weg eines jeden Reisebeitrags travels/

Mithilfe der Funktion addDoc von AngularFire kann ein Objekt in eine Sammlung eingefügt werden:

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;

	})
}

Daten aktualisieren und löschen

Anhand der UID eines beliebigen Reisebeitrags kann man den Pfad des in Firestore gespeicherten Dokuments ableiten, das dann mit den Funktionen updateFoc und deleteDoc von AngularFire gelesen, aktualisiert oder gelöscht werden kann:

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

Daten als Observable lesen

Da Reiseposten und Stopps entlang der Strecke nach der Erstellung geändert werden können, wäre es sinnvoller, Dokumentobjekte als Observables zu erhalten, um alle vorgenommenen Änderungen zu abonnieren. Diese Funktionalität wird von den Funktionen docData collectionData von @angular/fire/firestore angeboten.

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[]>
}

Stopps zu einem Reisebeitrag hinzufügen

Nachdem die Reisepostvorgänge nun eingerichtet sind, ist es an der Zeit, Stopps zu berücksichtigen, die in einer Untersammlung eines Reiseposts wie folgt vorhanden sein werden: travels/ /stops/ travels/ /stops/

Dies ist fast identisch mit dem Erstellen eines Reisebeitrags. Fordern Sie sich also heraus, es selbst umzusetzen, oder sehen Sie sich die folgende Implementierung an:

async  addStop(travelId: string) {
	...
	const  ref = await  addDoc(collection(this.firestore, `travels/${travelId}/stops`), stopData)
	setDoc(ref, {...stopData, id:  ref.id})
}

Hübsch! Die Firestore-Funktionen wurden im Reisedienst implementiert, sodass Sie sie jetzt in Aktion sehen können.

Verwendung von Firestore-Funktionen in der App

Navigieren Sie zu src/app/pages/my-travels/my-travels.component.ts und injizieren Sie TravelService , um seine Funktionen zu nutzen.

travelService = inject(TravelService);
travelsData$: Observable<Travel[]>;
stopsList$!: Observable<Stop[]>;
constructor() {
	this.travelsData$ = this.travelService.getCollectionData(`travels`) as  Observable<Travel[]>
}

TravelService wird im Konstruktor aufgerufen, um ein Observable-Array aller Reisen zu erhalten.

Für den Fall , dass nur die Reisen des aktuellen Benutzers benötigt werden, verwenden Sie die query .

Weitere Methoden zur Gewährleistung der Sicherheit umfassen die Implementierung von Sicherheitsregeln oder die Verwendung von Cloud Functions mit Firestore, wie in den optionalen Schritten unten beschrieben

Rufen Sie dann einfach die in TravelService implementierten Funktionen auf.

async  createTravel(userId: String) {
	this.travelService.addEmptyTravel(userId);
}

deleteTravel(travelId: String) {
	this.travelService.deleteData(`travels/${travelId}`)
}

Jetzt sollte die Seite „Meine Reisen“ funktionsfähig sein! Sehen Sie sich an, was in Ihrem Firestore-Emulator passiert, wenn Sie einen neuen Reisebeitrag erstellen.

Wiederholen Sie den Vorgang dann für die Aktualisierungsfunktionen in /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. Speicher konfigurieren

Sie implementieren nun Storage zum Speichern von Bildern und anderen Medientypen.

Cloud Firestore wird am besten zum Speichern strukturierter Daten wie JSON-Objekte verwendet. Cloud Storage dient zum Speichern von Dateien oder Blobs. In dieser App ermöglichen Sie Benutzern das Teilen ihrer Reisebilder.

Ebenso erfordert das Speichern und Aktualisieren von Dateien mit Storage bei Firestore eine eindeutige Kennung für jede Datei.

Lassen Sie uns die Funktionen in TraveService implementieren:

Hochladen einer Datei

Navigieren Sie zu src/app/services/travel.service.ts und fügen Sie Speicher von AngularFire ein:

export  class  TravelService {
firestore: Firestore = inject(Firestore);
auth: Auth = inject(Auth);
storage: Storage = inject(Storage);

Und implementieren Sie die Upload-Funktion:

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

Der Hauptunterschied zwischen dem Zugriff auf Dokumente aus Firestore und Dateien aus Cloud Storage besteht darin, dass beide zwar ordnerstrukturierten Pfaden folgen, die Kombination aus Basis-URL und Pfad jedoch über getDownloadURL abgerufen wird, die dann gespeichert und in a verwendet werden kann Datei.

Nutzung der Funktion in der App

Navigieren Sie zu src/app/components/edit-stop/edit-stop.component.ts und rufen Sie die Upload-Funktion auf mit:

	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);
}

Wenn das Bild hochgeladen wird, wird die Mediendatei selbst in den Speicher hochgeladen und die URL entsprechend im Dokument in Firestore gespeichert.

9. Bereitstellen der Anwendung

Jetzt können wir die Anwendung bereitstellen!

Kopieren Sie die firebase Konfigurationen von src/environments/environment.ts nach src/environments/environment.prod.ts und führen Sie Folgendes aus:

firebase deploy

Sie sollten etwa Folgendes sehen:

✔ 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. Herzlichen Glückwunsch!

Jetzt sollte Ihre Bewerbung vollständig und auf Firebase Hosting bereitgestellt sein! Alle Daten und Analysen sind jetzt in Ihrer Firebase-Konsole verfügbar.

Weitere Funktionen zu AngularFire, Funktionen und Sicherheitsregeln finden Sie unten in den optionalen Schritten sowie in anderen Firebase-Codelabs !

11. Optional: AngularFire-Authentifizierungsschutz

Neben der Firebase-Authentifizierung bietet AngularFire auch authentifizierungsbasierte Schutzmaßnahmen für Routen, sodass Benutzer mit unzureichendem Zugriff umgeleitet werden können. Dies trägt dazu bei, die App vor Benutzern zu schützen, die auf geschützte Daten zugreifen.

Importieren Sie in src/app/app-routing.module.ts

import {AuthGuard, redirectLoggedInTo, redirectUnauthorizedTo} from  '@angular/fire/auth-guard'

Anschließend können Sie Funktionen definieren, wann und wohin Benutzer auf bestimmten Seiten weitergeleitet werden sollen:

const  redirectUnauthorizedToLogin = () =>  redirectUnauthorizedTo(['signin']);
const  redirectLoggedInToTravels = () =>  redirectLoggedInTo(['my-travels']);

Dann fügen Sie sie einfach zu Ihren Routen hinzu:

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. Optional: Sicherheitsregeln

Sowohl Firestore als auch Cloud Storage verwenden Sicherheitsregeln ( firestore.rules bzw. security.rules ), um die Sicherheit durchzusetzen und Daten zu validieren.

Im Moment sind die Firestore- und Storage-Daten offen für Lese- und Schreibzugriffe, aber Sie möchten nicht, dass die Leute die Beiträge anderer ändern! Mithilfe von Sicherheitsregeln können Sie den Zugriff auf Ihre Sammlungen und Dokumente einschränken.

Firestore-Regeln

Um nur authentifizierten Benutzern das Anzeigen von Reisebeiträgen zu ermöglichen, gehen Sie zur Datei firestore.rules und fügen Sie Folgendes hinzu:

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

Sicherheitsregeln können auch zur Validierung von Daten verwendet werden:

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

Aufbewahrungsregeln

Ebenso können wir Sicherheitsregeln verwenden, um den Zugriff auf Speicherdatenbanken in storage.rules zu erzwingen. Beachten Sie, dass wir Funktionen auch für komplexere Prüfungen verwenden können:

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