Firebase Angular Web Frameworks Codelab

1. Was Sie erstellen

In diesem Codelab erstellen Sie einen Reiseblog mit einer Echtzeit-Karte für die Gruppenarbeit mit der neuesten Version unserer Angular-Bibliothek: AngularFire. Die fertige Webanwendung besteht aus einem Reiseblog, in dem Sie Bilder für jeden Ort hochladen können, den Sie besucht haben.

AngularFire wird zum Erstellen der Webanwendung verwendet, die Emulator Suite für lokale Tests, die Authentifizierung zum Überwachen von Nutzerdaten, Firestore und Storage zum Speichern von Daten und Medien, unterstützt von Cloud Functions, und schließlich Firebase Hosting zum Bereitstellen der App.

Lerninhalte

  • Lokale Entwicklung mit Firebase-Produkten und der Emulator Suite
  • Web-App mit AngularFire optimieren
  • Daten in Firestore dauerhaft speichern
  • Medien im Speicher dauerhaft speichern
  • App in Firebase Hosting bereitstellen
  • Mit Cloud Functions mit Datenbanken und APIs interagieren

Voraussetzungen

  • Node.js Version 10 oder höher
  • Ein Google-Konto zum Erstellen und Verwalten Ihres Firebase-Projekts
  • Firebase CLI Version 11.14.2 oder höher
  • Einen beliebigen Browser, z. B. Chrome
  • Grundlegende Kenntnisse von Angular und JavaScript

2. Beispielcode abrufen

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

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

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

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

In diesem Codelab wird nur das Webframework-Repository verwendet:

  • 📁 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-Ordner, bevor Sie die Webanwendung erstellen.

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

Firebase CLI installieren

Installieren Sie die Firebase CLI mit dem folgenden Befehl in einem Terminal:

npm install -g firebase-tools

Prüfen Sie mit dem folgenden Befehl, ob Ihre Firebase CLI-Version höher als 11.14.2 ist:

firebase  --version

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

npm update firebase-tools

3. Firebase-Projekt erstellen und einrichten

Firebase-Projekt erstellen

  1. Melden Sie sich in Firebase an.
  2. Klicken Sie in der Firebase Console auf Projekt hinzufügen und geben Sie als Namen für Ihr Firebase-Projekt <your-project> ein. Notieren Sie sich die Projekt-ID für Ihr Firebase-Projekt.
  3. Klicken Sie auf Projekt erstellen.

Wichtig: Ihr Firebase-Projekt heißt <your-project>, wird aber von Firebase automatisch mit einer eindeutigen Projekt-ID im Format <your-project>-1234 versehen. Anhand dieser eindeutigen Kennung wird Ihr Projekt tatsächlich identifiziert (auch in der Befehlszeile), während <your-project> nur ein Anzeigename ist.

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

  • Firebase Authentication ermöglicht es Ihren Nutzern, sich mühelos in der App anzumelden.
  • Cloud Firestore speichert strukturierte Daten in der Cloud und benachrichtigt Sie sofort, wenn sich Daten ändern.
  • Cloud Storage for Firebase speichert Dateien in der Cloud.
  • Firebase Hosting hostet und stellt Assets bereit.
  • Funktionen zur Interaktion mit internen und externen APIs.

Für einige dieser Produkte sind spezielle Konfigurationen erforderlich oder sie müssen über die Firebase Console aktiviert werden.

Dem Projekt eine Firebase-Web-App hinzufügen

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

Google Log-in für Firebase Authentication aktivieren

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

So aktivieren Sie die Google-Anmeldung:

  1. Suchen Sie in der Firebase Console im linken Bereich nach dem Abschnitt Build.
  2. Klicken Sie auf Authentifizierung und dann auf den Tab Anmeldemethode. Sie können auch auf diesen Link klicken, um direkt dorthin zu gelangen.
  3. Aktivieren Sie den Anmeldeanbieter Google und klicken Sie dann auf Speichern.
  4. Legen Sie den öffentlichen Namen Ihrer App auf <your-project-name> fest und wählen Sie im Drop-down-Menü eine E-Mail-Adresse für den Projektsupport aus.

Cloud Firestore aktivieren

  1. Klicken Sie im Abschnitt Build in der Firebase Console auf Firestore-Datenbank.
  2. Klicken Sie im Cloud Firestore-Bereich auf Datenbank erstellen.
  3. Legen Sie den Speicherort für Cloud Firestore-Daten fest. Sie können die Standardeinstellung beibehalten oder eine Region in Ihrer Nähe auswählen.

Cloud Storage aktivieren

Die Webanwendung nutzt Cloud Storage for Firebase zum Speichern, Hochladen und Teilen von Bildern.

  1. Klicken Sie in der Firebase Console im Bereich Build auf Speicher.
  2. Wenn die Schaltfläche Jetzt starten nicht angezeigt wird, ist Cloud Storage bereits

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

  1. Klicken Sie auf Jetzt starten.
  2. Lesen Sie den Haftungsausschluss zu den Sicherheitsregeln für Ihr Firebase-Projekt und klicken Sie dann auf Weiter.
  3. Der Cloud Storage-Speicherort ist standardmäßig mit der Region ausgewä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 Nutzer Beliebiges in Cloud Storage schreiben. Später in diesem Codelab werden wir unseren Speicher sicherer machen.

4. Verbindung mit Ihrem Firebase-Projekt herstellen

Mit der Firebase-Befehlszeile (Firebase CLI) können Sie Ihre Webanwendung lokal mit Firebase Hosting bereitstellen und in Ihrem Firebase-Projekt bereitstellen.

Achten Sie darauf, dass Ihre Befehlszeile auf das lokale webframework-Verzeichnis Ihrer App zugreift.

Verknüpfen Sie den Code der Webanwendung mit Ihrem Firebase-Projekt. Melden Sie sich zuerst in der Befehlszeile in 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

Führen Sie den folgenden Befehl aus, um AngularFire zur App hinzuzufügen:

ng add @angular/fire

Folgen Sie dann der Anleitung für die Befehlszeile und wählen Sie die Funktionen aus, die in Ihrem Firebase-Projekt vorhanden sind.

Firebase initialisieren

Führen Sie zum Initialisieren des Firebase-Projekts Folgendes aus:

firebase init

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

Emulatoren starten

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

firebase  emulators:start

Nach einiger Zeit sollte in etwa Folgendes zu sehen sein:

$  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 die Meldung ✔All emulators ready! angezeigt wird, können Sie die Emulatoren verwenden.

Es sollte die (noch) nicht funktionierende Benutzeroberfläche Ihrer Reise-App angezeigt werden:

Jetzt können wir loslegen.

5. Webanwendung mit den Emulatoren verbinden

Laut der Tabelle in den Emulator-Protokollen überwacht der Cloud Firestore-Emulator den Port 8080 und der Emulator für die Authentifizierung den Port 9099.

EmulatorUI öffnen

Rufen Sie in Ihrem Webbrowser http://127.0.0.1:4000/ auf. Die Benutzeroberfläche der Emulator Suite sollte angezeigt werden.

App so konfigurieren, dass sie die Emulatoren verwendet

Fügen Sie in src/app/app.module.ts der Importliste von AppModule den folgenden Code 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 so konfiguriert, dass lokale Emulatoren verwendet werden. So können Tests und die Entwicklung lokal durchgeführt werden.

6. Authentifizierung hinzufügen

Nachdem die Emulatoren für die App eingerichtet sind, können wir Authentifizierungsfunktionen hinzufügen, damit jeder Nutzer angemeldet ist, bevor er Nachrichten postet.

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

AngularFire Auth einfügen

Importieren Sie in src/app/pages/login-page/login-page.component.ts Auth aus @angular/fire/auth und fügen Sie es in LoginPageComponent ein. Authentifizierungsanbieter wie Google und Funktionen wie signin und signout können auch 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);
		})
	}
}

Die Anmeldeseite ist jetzt funktionsfähig. Melden Sie sich an und sehen Sie sich die Ergebnisse im Authentifizierungsemulator an.

7. Firestore konfigurieren

In diesem Schritt fügen Sie Funktionen hinzu, mit denen in Firestore gespeicherte Reiseblogbeiträge gepostet und aktualisiert werden können.

Ähnlich wie bei der Authentifizierung sind Firestore-Funktionen in AngularFire vorinstalliert. Jedes Dokument gehört zu einer Sammlung und jedes Dokument kann verschachtelte Sammlungen haben. Die path des Dokuments in Firestore ist erforderlich, um einen Reiseblogpost zu erstellen und zu aktualisieren.

TravelService implementieren

Da viele verschiedene Seiten Firestore-Dokumente in der Webanwendung lesen und aktualisieren müssen, können wir die Funktionen in src/app/services/travel.service.ts implementieren, um nicht wiederholt dieselben AngularFire-Funktionen auf jeder Seite einzuschleusen.

Beginnen Sie damit, Auth und Firestore wie im vorherigen Schritt in unseren Dienst einzuschleusen. Es ist auch nützlich, ein beobachtbares user$-Objekt 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);

Reisebeitrag hinzufügen

Reisebeiträge werden als Dokumente in Firestore gespeichert. Da Dokumente in Sammlungen vorhanden sein müssen, wird die Sammlung, die alle Reisebeiträge enthält, travels genannt. Der Pfad eines Reiseposts lautet also travels/

Mit der addDoc-Funktion 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 Reiseposts kann der Pfad des in Firestore gespeicherten Dokuments ermittelt werden, 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 Reisebeiträge und Zwischenstopps nach der Erstellung geändert werden können, ist es sinnvoller, Dokumentobjekte als Observables abzurufen, um alle Änderungen zu abonnieren. Diese Funktion wird von den Funktionen docData und 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[]>
}

Zwischenstopps zu einem Reisepost hinzufügen

Nachdem Sie die Funktionen für Reisebeiträge eingerichtet haben, können Sie sich nun mit Haltestellen befassen. Diese werden in einer Untersammlung eines Reisebeitrags wie hier dargestellt angezeigt: travels//stops/

Das ist fast identisch mit dem Erstellen eines Reiseposts. Du kannst es also selbst ausprobieren oder dir die Implementierung unten ansehen:

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

Hört sich gut an. Die Firestore-Funktionen wurden in den Reisedienst implementiert, sodass Sie sie jetzt in Aktion sehen können.

Firestore-Funktionen in der App verwenden

Rufen Sie src/app/pages/my-travels/my-travels.component.ts auf und fügen Sie TravelService ein, um die Funktionen zu verwenden.

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

Wenn nur die Fahrten des aktuellen Nutzers benötigt werden, verwenden Sie die query-Funktion.

Weitere Methoden zur Gewährleistung der Sicherheit sind die Implementierung von Sicherheitsregeln oder die Verwendung von Cloud Functions mit Firestore. Weitere Informationen finden Sie in den optionalen Schritten unten.

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

Die Seite „Meine Reisen“ sollte jetzt funktionieren. Sehen Sie sich an, was in Ihrem Firestore-Emulator passiert, wenn Sie einen neuen Reisebeitrag erstellen.

Wiederholen Sie dann den Vorgang 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 jetzt den Speicher, um Bilder und andere Medientypen zu speichern.

Cloud Firestore eignet sich am besten zum Speichern strukturierter Daten wie JSON-Objekte. Cloud Storage ist für das Speichern von Dateien oder Blobs konzipiert. In dieser App können Nutzer ihre Reisebilder teilen.

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

Implementieren wir die Funktionen in TraveService:

Datei hochladen

Rufen Sie src/app/services/travel.service.ts auf und fügen Sie Storage über AngularFire ein:

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

Implementieren Sie die Uploadfunktion:

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 Ordnerpfade verwenden, die Kombination aus Basis-URL und Pfad jedoch über die getDownloadURL abgerufen wird, die dann gespeichert und in einer -Datei verwendet werden kann.

Funktion in der App verwenden

Rufe src/app/components/edit-stop/edit-stop.component.ts auf und rufe die Uploadfunktion mit folgendem Code auf:

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

Beim Hochladen des Bildes wird die Mediendatei selbst in den Speicher hochgeladen und die URL entsprechend im Dokument in Firestore gespeichert.

9. Anwendung bereitstellen

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

Auf dem Bildschirm sollte Folgendes zu sehen sein:

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

Ihre Anwendung sollte jetzt fertig sein und auf Firebase Hosting bereitgestellt werden. Alle Daten und Analysen sind jetzt in der Firebase Console verfügbar.

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

11. Optional: AngularFire-Authentifizierungs-Guards

Neben Firebase Authentication bietet AngularFire auch authentifizierungsbasierte Guards für Routen, damit Nutzer mit unzureichendem Zugriff weitergeleitet werden können. So wird die App vor Nutzern geschützt, die auf geschützte Daten zugreifen.

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

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

Sie können dann Funktionen definieren, die festlegen, wann und wohin Nutzer auf bestimmten Seiten weitergeleitet werden sollen:

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

Fügen Sie sie dann einfach 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 zu erzwingen und Daten zu validieren.

Derzeit ist der Zugriff auf die Firestore- und Speicherdaten für Lese- und Schreibvorgänge offen. Sie möchten jedoch nicht, dass Nutzer die Beiträge anderer ändern können. Mit Sicherheitsregeln können Sie den Zugriff auf Ihre Sammlungen und Dokumente einschränken.

Firestore-Regeln

Wenn nur authentifizierte Nutzer Reisebeiträge sehen sollen, fügen Sie in der Datei firestore.rules 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;
	}
}

Speicherregeln

Ebenso können wir mithilfe von Sicherheitsregeln den Zugriff auf Speicherdatenbanken in storage.rules erzwingen. Für komplexere Prüfungen können auch Funktionen verwendet werden:

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