Firebase Angular Web Frameworks Codelab

1. Aufgaben

In diesem Codelab erledigst du einen Reiseblog mit einer Echtzeitkarte für die Zusammenarbeit und Aktuelles aus unserer Angular-Bibliothek: AngularFire. Die letzte Webanwendung wird aus einem Reiseblog bestehen, in dem Sie für alle besuchten Orte Bilder hochladen können.

AngularFire wird verwendet, um die Webanwendung zu erstellen, die Emulator Suite für lokale Tests, die Authentifizierung zum Nachverfolgen von Nutzerdaten, Firestore und Storage, um Daten und Medien dauerhaft zu speichern (unterstützt von Cloud Functions) und schließlich Firebase Hosting für die Bereitstellung der App.

Lerninhalte

  • Mit Firebase-Produkten lokal entwickeln – mit der Emulator Suite
  • Web-App mit AngularFire optimieren
  • So speichern Sie Ihre Daten in Firestore
  • Medien im Speicher dauerhaft speichern
  • App in Firebase Hosting bereitstellen
  • Cloud Functions für die Interaktion mit Datenbanken und APIs verwenden

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
  • Browser Ihrer Wahl, z. B. Chrome
  • Grundlegendes Verständnis 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 Firebase CLI mit diesem 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, führen Sie ein Update mithilfe der folgenden Schritte aus:

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 dem Firebase-Projekt den Namen <Ihr-Projekt>. Merken Sie sich die Projekt-ID Ihres Firebase-Projekts.
  3. Klicken Sie auf Projekt erstellen.

Wichtig: Ihr Firebase-Projekt erhält den Namen <Ihr-Projekt>, Firebase weist ihm jedoch automatisch eine eindeutige Projekt-ID im Format <Ihr-Projekt>-1234 zu. 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:

  • Mit der Firebase-Authentifizierung können sich Ihre Nutzer ganz einfach in Ihrer App anmelden.
  • 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.

Aktivieren Sie Google Log-in für Firebase Authentication.

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

So aktivieren Sie die Anmeldung über Google:

  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 hier 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 und Sie die folgenden Schritte nicht ausführen müssen.

  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 können Sie Firebase Hosting verwenden, um Ihre Web-App lokal sowie Ihre Web-App in Ihrem Firebase-Projekt bereitzustellen.

Prüfen Sie, ob die Befehlszeile auf das lokale Verzeichnis webframework 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 folgenden Befehl aus, um das Firebase-Projekt zu initialisieren:

firebase init

Folgen Sie dann den Aufforderungen in der Befehlszeile und wählen Sie 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.

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

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.

Anwendung zur Verwendung der Emulatoren weiterleiten

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 Status der Nutzerauthentifizierung 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 oder 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. 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 Reiseblogbeiträgen hinzu, die in Firestore gespeichert sind.

Ähnlich wie bei der Authentifizierung werden Firestore-Funktionen von AngularFire vorkonfiguriert. 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, wie im vorherigen Schritt, Auth und Firestore in unseren Dienst einzuschleusen. Auch das Definieren eines beobachtbaren user$-Objekts, das den aktuellen Authentifizierungsstatus überwacht, ist hilfreich.

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, erhält die Sammlung, die alle Reisebeiträge enthält, den Namen travels. Der Pfad eines Reiseposts lautet also travels/

Mit 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 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 beobachtbare Daten lesen

Da Reisebeiträge und Haltestellen auf der Route nach der Erstellung geändert werden können, ist es sinnvoller, Dokumentobjekte als Beobachtbare zu erhalten, um alle vorgenommenen Ä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 Reisebeitrag hinzufügen

Nachdem Sie die Reisebuchung eingerichtet haben, müssen auch Zwischenstopps berücksichtigt werden. Diese finden Sie unter der untergeordneten Sammlung eines Reisebeitrags: 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 Funktion query.

Weitere Methoden zur Gewährleistung der Sicherheit sind die Implementierung von Sicherheitsregeln oder die Verwendung von Cloud Functions mit Firestore, wie in den optionalen Schritten unten erläutert wird.

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 diesen Vorgang anschließend 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 ermöglichen Sie Nutzern damit, ihre Reisefotos zu 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 Sie 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);

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

Gehen Sie zu src/app/components/edit-stop/edit-stop.component.ts und rufen Sie die Upload-Funktion mit folgendem Befehl 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);
}

Wenn das Bild hochgeladen wird, wird die Mediendatei selbst in den Speicher hochgeladen und die URL wird 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 vollständig und in Firebase Hosting bereitgestellt sein. Alle Daten und Analysen sind jetzt in Ihrer 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-Auth-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'

Anschließend können Sie Funktionen dafür definieren, 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 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. Sie können Sicherheitsregeln verwenden, um den Zugriff auf Ihre Sammlungen und Dokumente einzuschränken.

Firestore-Regeln

Wenn Sie nur authentifizierten Nutzern erlauben möchten, Reisebeiträge anzusehen, rufen Sie die Datei firestore.rules auf 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;
	}
}

Speicherregeln

Ebenso können wir mithilfe von Sicherheitsregeln den Zugriff auf Speicherdatenbanken in storage.rules erzwingen. Beachten Sie, dass wir auch Funktionen 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;
		}
	}
}