1. Bevor Sie beginnen
In diesem Codelab erfahren Sie, wie Sie die Firebase Emulator Suite mit Flutter während der lokalen Entwicklung verwenden. Sie erfahren, wie Sie die E-Mail-Passwort-Authentifizierung über die Emulator Suite verwenden und wie Sie Daten im Firestore-Emulator lesen und schreiben. Schließlich arbeiten Sie mit dem Import und Export von Daten aus den Emulatoren, um bei jeder Rückkehr zur Entwicklung mit denselben gefälschten Daten zu arbeiten.
Voraussetzungen
Dieses Codelab setzt voraus, dass Sie über Flutter-Erfahrung verfügen. Wenn nicht, möchten Sie vielleicht zunächst die Grundlagen erlernen. Die folgenden Links sind hilfreich:
- Machen Sie eine Tour durch das Flutter Widget Framework
- Probieren Sie das Codelab „Write Your First Flutter App, Teil 1“ aus
Sie sollten auch über etwas Firebase-Erfahrung verfügen, aber es ist in Ordnung, wenn Sie Firebase noch nie zu einem Flutter-Projekt hinzugefügt haben. Wenn Sie mit der Firebase-Konsole nicht vertraut sind oder ganz neu bei Firebase sind, sehen Sie sich zunächst die folgenden Links an:
Was Sie erstellen werden
Dieses Codelab führt Sie durch die Erstellung einer einfachen Journaling-Anwendung. Die Anwendung verfügt über einen Anmeldebildschirm und einen Bildschirm, auf dem Sie frühere Journaleinträge lesen und neue erstellen können.
Was Sie lernen werden
Sie erfahren, wie Sie mit der Verwendung von Firebase beginnen und wie Sie die Firebase-Emulator-Suite in Ihren Flutter-Entwicklungsworkflow integrieren und verwenden. Diese Firebase-Themen werden behandelt:
Beachten Sie, dass diese Themen insoweit behandelt werden, als sie für die Abdeckung der Firebase-Emulator-Suite erforderlich sind. Dieses Codelab konzentriert sich auf das Hinzufügen eines Firebase-Projekts zu Ihrer Flutter-App und die Entwicklung mit der Firebase Emulator Suite. Es wird keine ausführlichen Diskussionen zu Firebase Authentication oder Firestore geben. Wenn Sie mit diesen Themen nicht vertraut sind, empfehlen wir Ihnen, mit dem Codelab „Firebase für Flutter kennenlernen“ zu beginnen.
Was du brauchen wirst
- Kenntnisse in Flutter und installiertem SDK
- Intellij JetBrains- oder VS Code-Texteditoren
- Google Chrome-Browser (oder Ihr anderes bevorzugtes Entwicklungsziel für Flutter. Einige Terminalbefehle in diesem Codelab gehen davon aus, dass Sie Ihre App auf Chrome ausführen)
2. Erstellen und richten Sie ein Firebase-Projekt ein
Die erste Aufgabe, die Sie erledigen müssen, ist die Erstellung eines Firebase-Projekts in der Webkonsole von Firebase. Ein Großteil dieses Codelabs wird sich auf die Emulator Suite konzentrieren, die eine lokal ausgeführte Benutzeroberfläche verwendet, aber Sie müssen zuerst ein vollständiges Firebase-Projekt einrichten.
Erstellen Sie ein Firebase-Projekt
- Melden Sie sich bei der Firebase-Konsole an.
- Klicken Sie in der Firebase-Konsole auf Projekt hinzufügen (oder Projekt erstellen ) und geben Sie einen Namen für Ihr Firebase-Projekt ein (z. B. „ Firebase-Flutter-Codelab“) .
- Klicken Sie sich durch die Projekterstellungsoptionen. Akzeptieren Sie die Firebase-Bedingungen, wenn Sie dazu aufgefordert werden. Überspringen Sie die Einrichtung von Google Analytics, da Sie Analytics für diese App nicht verwenden werden.
Weitere Informationen zu Firebase-Projekten finden Sie unter Grundlegendes zu Firebase-Projekten .
Die von Ihnen erstellte App verwendet zwei Firebase-Produkte, die für Flutter-Apps verfügbar sind:
- Firebase-Authentifizierung , damit sich Ihre Benutzer bei Ihrer App anmelden können.
- Cloud Firestore , um strukturierte Daten in der Cloud zu speichern und sofortige Benachrichtigungen zu erhalten, wenn sich Daten ändern.
Diese beiden Produkte erfordern eine spezielle Konfiguration oder müssen über die Firebase-Konsole aktiviert werden.
Aktivieren Sie Cloud Firestore
Die Flutter-App verwendet Cloud Firestore zum Speichern von Journaleinträgen.
Cloud Firestore aktivieren:
- Klicken Sie im Build- Bereich der Firebase-Konsole auf Cloud Firestore .
- Klicken Sie auf Datenbank erstellen .
- Wählen Sie die Option Im Testmodus starten . Lesen Sie den Haftungsausschluss zu den Sicherheitsregeln. Der Testmodus stellt sicher, dass Sie während der Entwicklung frei in die Datenbank schreiben können. Weiter klicken .
- Wählen Sie den Speicherort für Ihre Datenbank aus (Sie können einfach die Standardeinstellung verwenden). Beachten Sie, dass dieser Speicherort später nicht geändert werden kann.
- Klicken Sie auf Aktivieren .
3. Richten Sie die Flutter-App ein
Bevor wir beginnen, müssen Sie den Startercode herunterladen und die Firebase-CLI installieren.
Holen Sie sich den Startercode
Klonen Sie das GitHub-Repository über die Befehlszeile:
git clone https://github.com/flutter/codelabs.git flutter-codelabs
Alternativ, wenn Sie das CLI-Tool von GitHub installiert haben:
gh repo clone flutter/codelabs flutter-codelabs
Der Beispielcode sollte in das Verzeichnis flutter-codelabs
geklont werden, das den Code für eine Sammlung von Codelabs enthält. Der Code für dieses Codelab befindet sich in flutter-codelabs/firebase-emulator-suite
.
Die Verzeichnisstruktur unter flutter-codelabs/firebase-emulator-suite
besteht aus zwei Flutter-Projekten. Eine davon heißt complete
und Sie können darauf verweisen, wenn Sie weitermachen oder Ihren eigenen Code mit Querverweisen versehen möchten. Das andere Projekt heißt start
.
Der Code, mit dem Sie beginnen möchten, befindet sich im Verzeichnis flutter-codelabs/firebase-emulator-suite/start
. Öffnen oder importieren Sie dieses Verzeichnis in Ihre bevorzugte IDE.
cd flutter-codelabs/firebase-emulator-suite/start
Installieren Sie die Firebase-CLI
Die Firebase-CLI bietet Tools zum Verwalten Ihrer Firebase-Projekte. Für die Verwendung der Emulator Suite ist die CLI erforderlich, daher müssen Sie sie installieren.
Es gibt verschiedene Möglichkeiten, die CLI zu installieren. Wenn Sie MacOS oder Linux verwenden, ist es am einfachsten, diesen Befehl von Ihrem Terminal aus auszuführen:
curl -sL https://firebase.tools | bash
Nach der Installation der CLI müssen Sie sich bei Firebase authentifizieren.
- Melden Sie sich mit Ihrem Google-Konto bei Firebase an, indem Sie den folgenden Befehl ausführen:
firebase login
- Dieser Befehl verbindet Ihren lokalen Computer mit Firebase und gewährt Ihnen Zugriff auf Ihre Firebase-Projekte.
- Testen Sie, ob die CLI ordnungsgemäß installiert ist und Zugriff auf Ihr Konto hat, indem Sie Ihre Firebase-Projekte auflisten. Führen Sie den folgenden Befehl aus:
firebase projects:list
- Die angezeigte Liste sollte mit den in der Firebase-Konsole aufgeführten Firebase-Projekten übereinstimmen. Sie sollten mindestens Firebase-flutter-codelab sehen.
Installieren Sie die FlutterFire-CLI
Die FlutterFire-CLI basiert auf der Firebase-CLI und erleichtert die Integration eines Firebase-Projekts in Ihre Flutter-App.
Installieren Sie zunächst die CLI:
dart pub global activate flutterfire_cli
Stellen Sie sicher, dass die CLI installiert wurde. Führen Sie den folgenden Befehl im Flutter-Projektverzeichnis aus und stellen Sie sicher, dass die CLI das Hilfemenü ausgibt.
flutterfire --help
Verwenden Sie Firebase CLI und FlutterFire CLI, um Ihr Firebase-Projekt zu Ihrer Flutter-App hinzuzufügen
Wenn die beiden CLIs installiert sind, können Sie mit nur wenigen Terminalbefehlen einzelne Firebase-Produkte (wie Firestore) einrichten, die Emulatoren herunterladen und Firebase zu Ihrer Flutter-App hinzufügen.
Schließen Sie zunächst die Einrichtung von Firebase ab, indem Sie Folgendes ausführen:
firebase init
Dieser Befehl führt Sie durch eine Reihe von Fragen, die zum Einrichten Ihres Projekts erforderlich sind. Diese Screenshots zeigen den Ablauf:
- Wenn Sie aufgefordert werden, Funktionen auszuwählen, wählen Sie „Firestore“ und „Emulatoren“. (Es gibt keine Authentifizierungsoption, da keine Konfiguration verwendet wird, die aus Ihren Flutter-Projektdateien geändert werden kann.)
- Wählen Sie als Nächstes „Vorhandenes Projekt verwenden“ aus, wenn Sie dazu aufgefordert werden.
- Wählen Sie nun das Projekt aus, das Sie in einem vorherigen Schritt erstellt haben: flutter-firebase-codelab.
- Als Nächstes werden Ihnen eine Reihe von Fragen zur Benennung der zu generierenden Dateien gestellt. Ich schlage vor, bei jeder Frage die Eingabetaste zu drücken, um den Standardwert auszuwählen.
- Abschließend müssen Sie die Emulatoren konfigurieren. Wählen Sie Firestore und Authentifizierung aus der Liste aus und drücken Sie dann bei jeder Frage zu den spezifischen Ports, die für jeden Emulator verwendet werden sollen, die Eingabetaste. Sie sollten die Standardeinstellung „Ja“ auswählen, wenn Sie gefragt werden, ob Sie die Emulator-Benutzeroberfläche verwenden möchten.
Am Ende des Vorgangs sollten Sie eine Ausgabe sehen, die wie im folgenden Screenshot aussieht.
Wichtig : Ihre Ausgabe unterscheidet sich möglicherweise geringfügig von meiner, wie im Screenshot unten zu sehen ist, da die letzte Frage standardmäßig „Nein“ lautet, wenn Sie die Emulatoren bereits heruntergeladen haben.
Konfigurieren Sie FlutterFire
Als Nächstes können Sie FlutterFire verwenden, um den erforderlichen Dart-Code für die Verwendung von Firebase in Ihrer Flutter-App zu generieren.
flutterfire configure
Wenn dieser Befehl ausgeführt wird, werden Sie aufgefordert, auszuwählen, welches Firebase-Projekt Sie verwenden möchten und welche Plattformen Sie einrichten möchten. In diesem Codelab verwenden die Beispiele Flutter Web, Sie können Ihr Firebase-Projekt jedoch so einrichten, dass alle Optionen verwendet werden.
Die folgenden Screenshots zeigen die Eingabeaufforderungen, die Sie beantworten müssen.
Dieser Screenshot zeigt die Ausgabe am Ende des Prozesses. Wenn Sie mit Firebase vertraut sind, werden Sie feststellen, dass Sie keine Anwendungen in der Konsole erstellen mussten und die FlutterFire-CLI dies für Sie erledigt hat.
Fügen Sie Firebase-Pakete zur Flutter-App hinzu
Der letzte Einrichtungsschritt besteht darin, die relevanten Firebase-Pakete zu Ihrem Flutter-Projekt hinzuzufügen. Stellen Sie im Terminal sicher, dass Sie sich im Stammverzeichnis des Flutter-Projekts unter flutter-codelabs/firebase-emulator-suite/start
befinden. Führen Sie dann die drei folgenden Befehle aus:
flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add cloud_firestore
Dies sind die einzigen Pakete, die Sie in dieser Anwendung verwenden.
4. Firebase-Emulatoren aktivieren
Bisher sind die Flutter-App und Ihr Firebase-Projekt für die Verwendung der Emulatoren eingerichtet, Sie müssen dem Flutter-Code jedoch noch mitteilen, dass er ausgehende Firebase-Anfragen an die lokalen Ports umleiten soll.
Fügen Sie zunächst den Firebase-Initialisierungscode und den Emulator-Setup-Code zur main
in main.dart.
main.dart
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'app_state.dart'; import 'firebase_options.dart'; import 'logged_in_view.dart'; import 'logged_out_view.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); if (kDebugMode) { try { FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080); await FirebaseAuth.instance.useAuthEmulator('localhost', 9099); } catch (e) { // ignore: avoid_print print(e); } } runApp(MyApp()); }
Die ersten Codezeilen initialisieren Firebase. Wenn Sie mit Firebase in einer Flutter-App arbeiten, sollten Sie fast immer mit dem Aufruf von WidgetsFlutterBinding.ensureInitialized
und Firebase.initializeApp
beginnen.
Anschließend weist der Code, der mit der Zeile if (kDebugMode)
beginnt, Ihre App an, auf die Emulatoren und nicht auf ein Firebase-Produktionsprojekt abzuzielen. kDebugMode
stellt sicher, dass die Ausrichtung auf die Emulatoren nur dann erfolgt, wenn Sie sich in einer Entwicklungsumgebung befinden. Da kDebugMode
ein konstanter Wert ist, weiß der Dart-Compiler, dass er diesen Codeblock im Release-Modus vollständig entfernen muss.
Starten Sie die Emulatoren
Sie sollten die Emulatoren starten, bevor Sie die Flutter-App starten. Starten Sie zunächst die Emulatoren, indem Sie Folgendes im Terminal ausführen:
firebase emulators:start
Dieser Befehl startet die Emulatoren und stellt Localhost-Ports bereit, über die wir mit ihnen interagieren können. Wenn Sie diesen Befehl ausführen, sollten Sie eine Ausgabe ähnlich dieser sehen:
Diese Ausgabe zeigt Ihnen, welche Emulatoren ausgeführt werden und wo Sie die Emulatoren sehen können. Schauen Sie sich zunächst die Benutzeroberfläche des Emulators unter localhost:4000
an.
Dies ist die Homepage für die Benutzeroberfläche des lokalen Emulators. Es listet alle verfügbaren Emulatoren auf und jeder einzelne ist mit dem Status „Ein“ oder „Aus“ gekennzeichnet.
5. Der Firebase Auth-Emulator
Der erste Emulator, den Sie verwenden, ist der Authentifizierungsemulator. Beginnen Sie mit dem Auth-Emulator, indem Sie auf der Authentifizierungskarte in der Benutzeroberfläche auf „Zum Emulator gehen“ klicken. Daraufhin wird eine Seite angezeigt, die wie folgt aussieht:
Diese Seite weist Ähnlichkeiten mit der Seite der Auth-Webkonsole auf. Es verfügt über eine Tabelle, in der die Benutzer wie in der Online-Konsole aufgeführt sind, und ermöglicht das manuelle Hinzufügen von Benutzern. Ein großer Unterschied besteht darin, dass die einzige auf den Emulatoren verfügbare Authentifizierungsmethode die Verwendung von E-Mail und Passwort ist. Dies reicht für die lokale Entwicklung aus.
Als Nächstes werden Sie durch den Prozess des Hinzufügens eines Benutzers zum Firebase Auth-Emulator und der anschließenden Anmeldung dieses Benutzers über die Flutter-Benutzeroberfläche geführt.
Fügen Sie einen Benutzer hinzu
Klicken Sie auf die Schaltfläche „Benutzer hinzufügen“ und füllen Sie das Formular mit diesen Informationen aus:
- Anzeigename: Dash
- E-Mail: dash@email.com
- Passwort: Strichwort
Senden Sie das Formular ab und Sie werden sehen, dass die Tabelle jetzt einen Benutzer enthält. Jetzt können Sie den Code aktualisieren, um sich mit diesem Benutzer anzumelden.
login_out_view.dart
Der einzige Code im LoggedOutView
-Widget, der aktualisiert werden muss, ist der Rückruf, der ausgelöst wird, wenn ein Benutzer die Anmeldeschaltfläche drückt. Aktualisieren Sie den Code so, dass er wie folgt aussieht:
class LoggedOutView extends StatelessWidget { final AppState state; const LoggedOutView({super.key, required this.state}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Firebase Emulator Suite Codelab'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Please log in', style: Theme.of(context).textTheme.displaySmall, ), Padding( padding: const EdgeInsets.all(8.0), child: ElevatedButton( onPressed: () async { await state.logIn('dash@email.com', 'dashword').then((_) { if (state.user != null) { context.go('/'); } }); }, child: const Text('Log In'), ), ), ], ), ), ); } }
Der aktualisierte Code ersetzt die TODO
Strings durch die E-Mail-Adresse und das Passwort, die Sie im Authentifizierungsemulator erstellt haben. Und in der nächsten Zeile wurde die if(true)
-Zeile durch Code ersetzt, der prüft, ob state.user
null ist. Der Code in AppClass
bringt mehr Licht ins Dunkel.
app_state.dart
Zwei Teile des Codes in AppState
müssen aktualisiert werden. Geben Sie dem Klassenmitglied AppState.user zunächst den Typ User
aus dem Paket firebase_auth
und nicht den Typ Object
.
Zweitens füllen Sie die AppState.login
Methode wie unten gezeigt aus:
import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'entry.dart'; class AppState { AppState() { _entriesStreamController = StreamController.broadcast(onListen: () { _entriesStreamController.add([ Entry( date: '10/09/2022', text: lorem, title: '[Example] My Journal Entry', ) ]); }); } User? user; // <-- changed variable type Stream<List<Entry>> get entries => _entriesStreamController.stream; late final StreamController<List<Entry>> _entriesStreamController; Future<void> logIn(String email, String password) async { final credential = await FirebaseAuth.instance .signInWithEmailAndPassword(email: email, password: password); if (credential.user != null) { user = credential.user!; _listenForEntries(); } else { print('no user!'); } } // ... }
Die Typdefinition für Benutzer lautet jetzt User?
. Diese User
Klasse stammt von Firebase Auth und stellt benötigte Informationen wie User.displayName
bereit, die gleich besprochen werden.
Dies ist der grundlegende Code, der benötigt wird, um einen Benutzer mit einer E-Mail-Adresse und einem Passwort in Firebase Auth anzumelden. Zur Anmeldung wird FirebaseAuth aufgerufen, wodurch ein Future<UserCredential>
-Objekt zurückgegeben wird. Wenn die Zukunft abgeschlossen ist, prüft dieser Code, ob ein User
an UserCredential
angehängt ist. Wenn das Anmeldeinformationsobjekt einen Benutzer enthält, hat sich ein Benutzer erfolgreich angemeldet und die AppState.user
Eigenschaft kann festgelegt werden. Ist dies nicht der Fall, liegt ein Fehler vor und die Meldung wird gedruckt.
Beachten Sie, dass die einzige Codezeile in dieser Methode, die spezifisch für diese App ist (und nicht der allgemeine FirebaseAuth-Code), der Aufruf der _listenForEntries
Methode ist, der im nächsten Schritt behandelt wird.
TODO: Aktionssymbol – Laden Sie Ihre App neu und klicken Sie beim Rendern auf die Schaltfläche „Anmelden“. Dadurch navigiert die App zu einer Seite mit der Aufschrift „Willkommen zurück, Person!“ oben. Die Authentifizierung muss funktionieren, da Sie damit zu dieser Seite navigieren können. Es muss jedoch eine geringfügige Aktualisierung an logged_in_view.dart
vorgenommen werden, um den tatsächlichen Namen des Benutzers anzuzeigen.
login_in_view.dart
Ändern Sie die erste Zeile in der LoggedInView.build
-Methode:
class LoggedInView extends StatelessWidget { final AppState state; LoggedInView({super.key, required this.state}); final PageController _controller = PageController(initialPage: 1); @override Widget build(BuildContext context) { final name = state.user!.displayName ?? 'No Name'; return Scaffold( // ...
Diese Zeile ruft nun den displayName
aus der User
Eigenschaft des AppState
Objekts ab. Dieser displayName
wurde im Emulator festgelegt, als Sie Ihren ersten Benutzer definiert haben. Ihre App sollte jetzt „Willkommen zurück, Dash!“ anzeigen. wenn Sie sich anmelden, und nicht TODO
.
6. Lesen und Schreiben von Daten in den Firestore-Emulator
Schauen Sie sich zunächst den Firestore-Emulator an. Klicken Sie auf der Startseite der Emulator-Benutzeroberfläche ( localhost:4000
) auf der Firestore-Karte auf „Zum Emulator gehen“. Es sollte so aussehen:
Emulator:
Firebase-Konsole:
Wenn Sie Erfahrung mit Firestore haben, werden Sie feststellen, dass diese Seite der Firestore-Seite der Firebase-Konsole ähnelt. Es gibt jedoch einige bemerkenswerte Unterschiede.
- Sie können alle Daten mit einem Tastendruck löschen. Dies wäre bei Produktionsdaten gefährlich, ist aber für eine schnelle Iteration hilfreich! Wenn Sie an einem neuen Projekt arbeiten und sich Ihr Datenmodell ändert, ist das leicht zu bereinigen.
- Es gibt einen Reiter „Anfragen“. Auf dieser Registerkarte können Sie eingehende Anfragen an diesen Emulator überwachen. Ich werde diese Registerkarte gleich ausführlicher besprechen.
- Es gibt keine Registerkarten für Regeln, Indizes oder Verwendung. Es gibt ein Tool (wird im nächsten Abschnitt besprochen), das beim Schreiben von Sicherheitsregeln hilft, Sie können jedoch keine Sicherheitsregeln für den lokalen Emulator festlegen.
Um diese Liste zusammenzufassen: Diese Version von Firestore bietet mehr Tools, die während der Entwicklung nützlich sind, und entfernt Tools, die in der Produktion benötigt werden.
Schreiben Sie an Firestore
Bevor Sie die Registerkarte „Anfragen“ im Emulator besprechen, stellen Sie zunächst eine Anfrage. Dies erfordert Code-Updates. Beginnen Sie damit, das Formular in der App zu verknüpfen, um einen neuen Entry
in Firestore zu schreiben.
Der allgemeine Ablauf zum Einreichen eines Entry
ist:
- Der Benutzer füllt das Formular aus und klickt auf die Schaltfläche
Submit
. - Die Benutzeroberfläche ruft
AppState.writeEntryToFirebase
auf -
AppState.writeEntryToFirebase
fügt Firebase einen Eintrag hinzu
Der in Schritt 1 oder 2 enthaltene Code muss nicht geändert werden. Der einzige Code, der für Schritt 3 hinzugefügt werden muss, wird in der AppState
Klasse hinzugefügt. Nehmen Sie die folgende Änderung an AppState.writeEntryToFirebase
vor.
app_state.dart
import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'entry.dart'; class AppState { AppState() { _entriesStreamController = StreamController.broadcast(onListen: () { _entriesStreamController.add([ Entry( date: '10/09/2022', text: lorem, title: '[Example] My Journal Entry', ) ]); }); } User? user; Stream<List<Entry>> get entries => _entriesStreamController.stream; late final StreamController<List<Entry>> _entriesStreamController; Future<void> logIn(String email, String password) async { final credential = await FirebaseAuth.instance .signInWithEmailAndPassword(email: email, password: password); if (credential.user != null) { user = credential.user!; _listenForEntries(); } else { print('no user!'); } } void writeEntryToFirebase(Entry entry) { FirebaseFirestore.instance.collection('Entries').add(<String, String>{ 'title': entry.title, 'date': entry.date.toString(), 'text': entry.text, }); } // ... }
Der Code in der writeEntryToFirebase-Methode ruft einen Verweis auf die Sammlung namens „Entries“ in Firestore ab. Anschließend wird ein neuer Eintrag hinzugefügt, der vom Typ Map<String, String>
sein muss.
In diesem Fall war die Sammlung „Einträge“ in Firestore nicht vorhanden, daher hat Firestore eine erstellt.
Nachdem Sie diesen Code hinzugefügt haben, laden Sie Ihre App im laufenden Betrieb neu oder starten Sie sie neu, melden Sie sich an und navigieren Sie zur EntryForm
Ansicht. Sie können das Formular mit beliebigen Strings
ausfüllen. (Das Datumsfeld nimmt einen beliebigen String an, da es für dieses Codelab vereinfacht wurde. Es verfügt nicht über eine starke Validierung und kümmert sich in keiner Weise um DateTime
Objekte.)
Klicken Sie im Formular auf „Senden“. In der App passiert nichts, aber Sie können Ihren neuen Eintrag in der Benutzeroberfläche des Emulators sehen.
Die Registerkarte „Anfragen“ im Firestore-Emulator
Navigieren Sie in der Benutzeroberfläche zum Firestore-Emulator und sehen Sie sich die Registerkarte „Daten“ an. Sie sollten sehen, dass sich jetzt im Stammverzeichnis Ihrer Datenbank eine Sammlung mit dem Namen „Entries“ befindet. Das Dokument sollte die gleichen Informationen enthalten, die Sie in das Formular eingegeben haben.
Dies bestätigt, dass AppState.writeEntryToFirestore
funktioniert hat, und jetzt können Sie die Anfrage auf der Registerkarte „Anfragen“ weiter untersuchen. Klicken Sie jetzt auf diese Registerkarte.
Anfragen zum Firestore-Emulator
Hier sollten Sie eine Liste sehen, die etwa so aussieht:
Sie können auf jedes dieser Listenelemente klicken und viele hilfreiche Informationen sehen. Klicken Sie auf den Listeneintrag CREATE
, der Ihrer Anfrage zum Erstellen eines neuen Journaleintrags entspricht. Sie sehen eine neue Tabelle, die so aussieht:
Wie bereits erwähnt, bietet der Firestore-Emulator Tools zum Entwickeln der Sicherheitsregeln Ihrer App. Diese Ansicht zeigt genau, welche Zeile in Ihren Sicherheitsregeln diese Anfrage bestanden hat (oder fehlgeschlagen ist, falls dies der Fall war). In einer robusteren App können die Sicherheitsregeln wachsen und mehrere Autorisierungsprüfungen umfassen. Diese Ansicht wird zum Schreiben und Debuggen dieser Autorisierungsregeln verwendet.
Es bietet außerdem eine einfache Möglichkeit, jeden Teil dieser Anfrage zu überprüfen, einschließlich der Metadaten und der Authentifizierungsdaten. Diese Daten werden zum Schreiben komplexer Autorisierungsregeln verwendet.
Lesung aus Firestore
Firestore nutzt die Datensynchronisierung, um aktualisierte Daten an verbundene Geräte zu übertragen. Im Flutter-Code können Sie Firestore-Sammlungen und -Dokumente anhören (oder abonnieren) und Ihr Code wird bei jeder Datenänderung benachrichtigt. In dieser App erfolgt die Überwachung auf Firestore-Updates in der Methode AppState._listenForEntries
.
Dieser Code funktioniert in Verbindung mit StreamController
und Stream
namens AppState._entriesStreamController
bzw. AppState.entries
. Dieser Code ist bereits geschrieben, ebenso wie der gesamte Code, der in der Benutzeroberfläche zum Anzeigen der Daten aus Firestore erforderlich ist.
Aktualisieren Sie die _listenForEntries
-Methode so, dass sie mit dem folgenden Code übereinstimmt:
app_state.dart
import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'entry.dart'; class AppState { AppState() { _entriesStreamController = StreamController.broadcast(onListen: () { _entriesStreamController.add([ Entry( date: '10/09/2022', text: lorem, title: '[Example] My Journal Entry', ) ]); }); } User? user; Stream<List<Entry>> get entries => _entriesStreamController.stream; late final StreamController<List<Entry>> _entriesStreamController; Future<void> logIn(String email, String password) async { final credential = await FirebaseAuth.instance .signInWithEmailAndPassword(email: email, password: password); if (credential.user != null) { user = credential.user!; _listenForEntries(); } else { print('no user!'); } } void writeEntryToFirebase(Entry entry) { FirebaseFirestore.instance.collection('Entries').add(<String, String>{ 'title': entry.title, 'date': entry.date.toString(), 'text': entry.text, }); } void _listenForEntries() { FirebaseFirestore.instance .collection('Entries') .snapshots() .listen((event) { final entries = event.docs.map((doc) { final data = doc.data(); return Entry( date: data['date'] as String, text: data['text'] as String, title: data['title'] as String, ); }).toList(); _entriesStreamController.add(entries); }); } // ... }
Dieser Code überwacht die Sammlung „Entries“ im Firestore. Wenn Firestore diesen Client benachrichtigt, dass neue Daten vorliegen, übergibt er diese Daten und der Code in _listenForEntries
ändert alle seine untergeordneten Dokumente in ein Objekt, das unsere App verwenden kann ( Entry
). Anschließend werden diese Einträge dem StreamController
namens _entriesStreamController
hinzugefügt (auf den die Benutzeroberfläche lauscht). Dieser Code ist das einzige erforderliche Update.
Denken Sie abschließend daran, dass die AppState.logIn
Methode einen Aufruf an _listenForEntries
durchführt, der den Abhörvorgang startet, nachdem sich ein Benutzer angemeldet hat.
// ... Future<void> logIn(String email, String password) async { final credential = await FirebaseAuth.instance .signInWithEmailAndPassword(email: email, password: password); if (credential.user != null) { user = credential.user!; _listenForEntries(); } else { print('no user!'); } } // ...
Führen Sie nun die App aus. Es sollte so aussehen:
7. Daten in den Emulator exportieren und importieren
Firebase-Emulatoren unterstützen den Import und Export von Daten. Mithilfe der Importe und Exporte können Sie die Entwicklung mit denselben Daten fortsetzen, wenn Sie eine Entwicklungspause einlegen und dann fortfahren. Sie können Datendateien auch an Git übergeben, und andere Entwickler, mit denen Sie zusammenarbeiten, können mit denselben Daten arbeiten.
Emulatordaten exportieren
Exportieren Sie zunächst die bereits vorhandenen Emulatordaten. Während die Emulatoren noch laufen, öffnen Sie ein neues Terminalfenster und geben Sie den folgenden Befehl ein:
firebase emulators:export ./emulators_data
.emulators_data
ist ein Argument, das Firebase mitteilt, wohin die Daten exportiert werden sollen. Wenn das Verzeichnis nicht existiert, wird es erstellt. Sie können für dieses Verzeichnis einen beliebigen Namen verwenden.
Wenn Sie diesen Befehl ausführen, sehen Sie diese Ausgabe in dem Terminal, in dem Sie den Befehl ausgeführt haben:
i Found running emulator hub for project flutter-firebase-codelab-d6b79 at http://localhost:4400 i Creating export directory /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data i Exporting data to: /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data ✔ Export complete
Und wenn Sie zum Terminalfenster wechseln, in dem die Emulatoren ausgeführt werden, sehen Sie diese Ausgabe:
i emulators: Received export request. Exporting data to /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data. ✔ emulators: Export complete.
Und schließlich, wenn Sie in Ihrem Projektverzeichnis nachsehen, sollten Sie ein Verzeichnis namens ./emulators_data
sehen, das neben anderen Metadatendateien JSON
Dateien mit den von Ihnen gespeicherten Daten enthält.
Emulatordaten importieren
Jetzt können Sie diese Daten als Teil Ihres Entwicklungsworkflows importieren und dort beginnen, wo Sie aufgehört haben.
Stoppen Sie zunächst die Emulatoren, wenn sie ausgeführt werden, indem Sie in Ihrem Terminal CTRL+C
drücken.
Führen Sie als Nächstes den Befehl emulators:start
, den Sie bereits gesehen haben, jedoch mit einer Markierung, die angibt, welche Daten importiert werden sollen:
firebase emulators:start --import ./emulators_data
Wenn die Emulatoren aktiv sind, navigieren Sie zur Emulator-Benutzeroberfläche unter localhost:4000
. Dort sollten dieselben Daten angezeigt werden, mit denen Sie zuvor gearbeitet haben.
Exportieren Sie Daten automatisch, wenn Sie Emulatoren schließen
Sie können Daten auch automatisch exportieren, wenn Sie die Emulatoren beenden, anstatt am Ende jeder Entwicklungssitzung daran zu denken, die Daten zu exportieren.
Wenn Sie Ihre Emulatoren starten, führen Sie den Befehl emulators:start
mit zwei zusätzlichen Flags aus.
firebase emulators:start --import ./emulators_data --export-on-exit
Voila! Ihre Daten werden nun gespeichert und jedes Mal neu geladen, wenn Sie mit den Emulatoren für dieses Projekt arbeiten. Sie können auch ein anderes Verzeichnis als Argument für das –export-on-exit flag
angeben, es wird jedoch standardmäßig das an –import
übergebene Verzeichnis verwendet.
Sie können auch jede beliebige Kombination dieser Optionen verwenden. Dies ist der Hinweis aus den Dokumenten : Das Exportverzeichnis kann mit diesem Flag angegeben werden: firebase emulators:start --export-on-exit=./saved-data
. Wenn --import
verwendet wird, ist der Exportpfad standardmäßig derselbe; zum Beispiel: firebase emulators:start --import=./data-path --export-on-exit
. Übergeben Sie schließlich, falls gewünscht, unterschiedliche Verzeichnispfade an die Flags --import
und --export-on-exit
.
8. Herzlichen Glückwunsch!
Sie haben die Inbetriebnahme des Firebase-Emulators und Flutter abgeschlossen. Den fertigen Code für dieses Codelab finden Sie im Verzeichnis „complete“ auf Github: Flutter Codelabs
Was wir abgedeckt haben
- Einrichten einer Flutter-App zur Verwendung von Firebase
- Einrichten eines Firebase-Projekts
- FlutterFire-CLI
- Firebase-CLI
- Firebase-Authentifizierungsemulator
- Firebase Firestore-Emulator
- Emulatordaten importieren und exportieren
Nächste Schritte
- Erfahren Sie mehr über die Verwendung von Firestore und Authentifizierung in Flutter: Lernen Sie Firebase für Flutter Codelab kennen
- Entdecken Sie andere Firebase-Tools, die Emulatoren anbieten:
- Cloud-Speicher
- Cloud-Funktionen
- Echtzeitdatenbank
- Entdecken Sie die FlutterFire-Benutzeroberfläche , um Ihrer App schnell die Google-Authentifizierung hinzuzufügen.
Erfahren Sie mehr
- Firebase-Website: firebase.google.com
- Flutter-Site: flutter.dev
- FlutterFire Firebase Flutter-Widgets: firebase.flutter.dev
- Firebase-YouTube-Kanal
- Flutter YouTube-Kanal
Sparky ist stolz auf dich!