1. Hinweis
In diesem Codelab erfahren Sie, wie Sie die Firebase Emulator Suite mit Flutter bei 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. Zum Schluss importieren und exportieren Sie Daten aus den Emulatoren, damit Sie bei der Entwicklung immer mit denselben fiktiven Daten arbeiten.
Vorbereitung
In diesem Codelab wird davon ausgegangen, dass Sie bereits Erfahrung mit Flutter haben. Falls nicht, sollten Sie sich zunächst mit den Grundlagen vertraut machen. Die folgenden Links sind hilfreich:
- Flutter-Widget-Framework kennenlernen
- Codelab Write Your First Flutter App, Teil 1 ausprobieren
Außerdem sollten Sie bereits einige Firebase-Kenntnisse haben, das ist aber in Ordnung, wenn Sie Firebase noch nie einem Flutter-Projekt hinzugefügt haben. Wenn Sie mit der Firebase Console nicht vertraut sind oder Firebase noch nicht kennen, sehen Sie sich zuerst die folgenden Links an:
Was Sie erstellen
In diesem Codelab erfahren Sie, wie Sie eine einfache Tagebuch-App erstellen. Die Anwendung hat einen Anmeldebildschirm und einen Bildschirm, auf dem Sie frühere Tagebucheinträge lesen und neue erstellen können.
Lerninhalte
Sie erfahren, wie Sie Firebase verwenden und die Firebase Emulator Suite in Ihren Flutter-Entwicklungsworkflow einbinden und verwenden. Folgende Firebase-Themen werden behandelt:
Diese Themen werden nur insoweit behandelt, wie sie für die Firebase-Emulator-Suite erforderlich sind. In diesem Codelab erfahren Sie, wie Sie Ihrer Flutter-App ein Firebase-Projekt hinzufügen und mit der Firebase Emulator Suite entwickeln. 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 „Einführung in Firebase für Flutter“ zu beginnen.
Voraussetzungen
- Grundkenntnisse in Flutter und das installierte SDK
- IntelliJ JetBrains oder VS Code-Texteditoren
- Google Chrome-Browser (oder Ihr bevorzugtes Entwicklungsziel für Flutter) Bei einigen Terminalbefehlen in diesem Codelab wird davon ausgegangen, dass Sie Ihre App in Chrome ausführen.
2. Firebase-Projekt erstellen und einrichten
Als Erstes müssen Sie ein Firebase-Projekt in der Firebase-Webkonsole erstellen. Der Großteil dieses Codelabs konzentriert sich auf die Emulator Suite, die eine lokal ausgeführte Benutzeroberfläche verwendet. Sie müssen jedoch zuerst ein vollständiges Firebase-Projekt einrichten.
Firebase-Projekt erstellen
- Melden Sie sich in der Firebase Console an.
- Klicken Sie in der Firebase Console 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 Optionen für die Projekterstellung. Akzeptieren Sie die Firebase-Nutzungsbedingungen, 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 Firebase-Projekte verstehen.
Die App, die Sie erstellen, verwendet zwei Firebase-Produkte, die für Flutter-Apps verfügbar sind:
- Firebase Authentication, damit sich Ihre Nutzer in Ihrer App anmelden können.
- Cloud Firestore speichert strukturierte Daten in der Cloud und benachrichtigt Sie sofort, wenn sich Daten ändern.
Diese beiden Produkte erfordern eine spezielle Konfiguration oder müssen über die Firebase Console aktiviert werden.
Cloud Firestore aktivieren
Die Flutter-App verwendet Cloud Firestore, um Tagebucheinträge zu speichern.
So aktivieren Sie Cloud Firestore:
- Klicken Sie in der Firebase Console im Abschnitt Build auf Cloud Firestore.
- Klicken Sie auf Datenbank erstellen.
- Wählen Sie die Option Im Testmodus starten aus. Lesen Sie den Haftungsausschluss zu den Sicherheitsregeln. Der Testmodus stellt sicher, dass Sie während der Entwicklung ungehindert in die Datenbank schreiben können. Klicken Sie auf Weiter.
- Wählen Sie den Speicherort für Ihre Datenbank aus (Sie können einfach den Standardwert verwenden). Dieser Speicherort kann später nicht mehr geändert werden.
- Klicken Sie auf Aktivieren.
3. Flutter-App einrichten
Sie müssen den Startercode herunterladen und die Firebase CLI installieren, bevor wir beginnen.
Startcode abrufen
Klonen Sie das GitHub-Repository über die Befehlszeile:
git clone https://github.com/flutter/codelabs.git flutter-codelabs
Alternativ können Sie auch die GitHub-Befehlszeile verwenden:
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 heißt complete
, auf die Sie verweisen können, wenn Sie überspringen möchten oder einen Querverweis auf Ihren eigenen Code vornehmen 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
Firebase CLI installieren
Die Firebase CLI bietet Tools zum Verwalten Ihrer Firebase-Projekte. Sie müssen die Befehlszeile installieren, um die Emulator Suite zu verwenden.
Es gibt verschiedene Möglichkeiten, die Befehlszeile zu installieren. Wenn Sie macOS oder Linux verwenden, ist die einfachste Methode, diesen Befehl über das Terminal auszuführen:
curl -sL https://firebase.tools | bash
Nach der Installation der Befehlszeile müssen Sie sich bei Firebase authentifizieren.
- Melden Sie sich mit Ihrem Google-Konto in Firebase an. Führen Sie dazu den folgenden Befehl aus:
firebase login
- Dieser Befehl verbindet Ihren lokalen Computer mit Firebase und gewährt Ihnen Zugriff auf Ihre Firebase-Projekte.
- Prüfen Sie, ob die Befehlszeile richtig installiert ist und Zugriff auf Ihr Konto hat, indem Sie Ihre Firebase-Projekte auflisten. Führen Sie dazu diesen Befehl aus:
firebase projects:list
- Die angezeigte Liste sollte mit den Firebase-Projekten in der Firebase Console übereinstimmen. Sie sollten mindestens „firebase-flutter-codelab“ sehen.
FlutterFire CLI installieren
Die FlutterFire CLI basiert auf der Firebase CLI und erleichtert die Einbindung eines Firebase-Projekts in Ihre Flutter-App.
Installieren Sie zuerst die Befehlszeile:
dart pub global activate flutterfire_cli
Prüfen Sie, ob die Befehlszeile installiert wurde. Führen Sie den folgenden Befehl im Flutter-Projektverzeichnis aus und prüfen Sie, ob die Befehlszeile das Hilfemenü ausgibt.
flutterfire --help
Firebase CLI und FlutterFire CLI verwenden, um der Flutter-App Ihr Firebase-Projekt hinzuzufügen
Wenn Sie die beiden Befehlszeilen installiert haben, können Sie einzelne Firebase-Produkte wie Firestore einrichten, die Emulatoren herunterladen und Firebase mit nur wenigen Terminalbefehlen zu Ihrer Flutter-App hinzufügen.
Führen Sie zuerst den folgenden Befehl aus, um die Firebase-Einrichtung abzuschließen:
firebase init
Mit diesem Befehl werden Sie durch eine Reihe von Fragen geführt, die für die Einrichtung Ihres Projekts erforderlich sind. Diese Screenshots zeigen den Ablauf:
- Wählen Sie „Firestore“ und „Emulatoren“ aus. Es gibt keine Authentifizierungsoption, da keine Konfiguration verwendet wird, die über Ihre 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 einige Fragen zum Benennen der generierten Dateien gestellt. Drücken Sie bei jeder Frage die Eingabetaste, um den Standardwert auszuwählen.
- Zum Schluss müssen Sie die Emulatoren konfigurieren. Wählen Sie in der Liste „Firestore“ und „Authentifizierung“ aus und drücken Sie bei jeder Frage zu den Ports, die für jeden Emulator verwendet werden sollen, die Eingabetaste. Wenn Sie gefragt werden, ob Sie die Emulator-Benutzeroberfläche verwenden möchten, wählen Sie die Standardeinstellung Ja aus.
Am Ende des Vorgangs sollte die Ausgabe in etwa so aussehen wie im folgenden Screenshot.
Wichtig: Ihre Ausgabe kann sich leicht von meiner im Screenshot unten unterscheiden, da die letzte Frage standardmäßig mit „Nein“ beantwortet wird, wenn Sie die Emulatoren bereits heruntergeladen haben.
FlutterFire konfigurieren
Als Nächstes können Sie mit FlutterFire den erforderlichen Dart-Code generieren, um Firebase in Ihrer Flutter-App zu verwenden.
flutterfire configure
Wenn Sie diesen Befehl ausführen, werden Sie aufgefordert, auszuwählen, welches Firebase-Projekt Sie verwenden und welche Plattformen Sie einrichten möchten. In diesem Codelab wird in den Beispielen Flutter Web verwendet. Sie können Ihr Firebase-Projekt jedoch so einrichten, dass alle Optionen verwendet werden.
Die folgenden Screenshots zeigen die Prompts, die Sie beantworten müssen.
Dieser Screenshot zeigt die Ausgabe am Ende des Vorgangs. Wenn Sie mit Firebase vertraut sind, werden Sie feststellen, dass Sie keine Anwendungen in der Console erstellen mussten, sondern dass die FlutterFire-Befehlszeile dies für Sie erledigt hat.
Firebase-Pakete zur Flutter-App hinzufügen
Im letzten Einrichtungsschritt fügen Sie Ihrem Flutter-Projekt die relevanten Firebase-Pakete hinzu. Prüfen Sie im Terminal, ob 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 so eingerichtet, dass Sie die Emulatoren verwenden können. Sie müssen jedoch dem Flutter-Code noch mitteilen, dass ausgehende Firebase-Anfragen an die lokalen Ports weitergeleitet werden sollen.
Fügen Sie zuerst den Firebase-Initialisierungscode und den Emulator-Einrichtungscode der main
-Funktion in main.dart.
hinzu.
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()); }
In den ersten Codezeilen wird Firebase initialisiert. Wenn Sie mit Firebase in einer Flutter-App arbeiten, sollten Sie zuerst WidgetsFlutterBinding.ensureInitialized
und Firebase.initializeApp
aufrufen.
Anschließend wird in der Zeile if (kDebugMode)
festgelegt, dass Ihre App auf die Emulatoren und nicht auf ein Produktions-Firebase-Projekt ausgerichtet werden soll. kDebugMode
sorgt dafür, dass ein Targeting auf die Emulatoren nur erfolgt, wenn Sie sich in einer Entwicklungsumgebung befinden. Da kDebugMode
ein konstanter Wert ist, weiß der Dart-Compiler, dass dieser Codeblock im Release-Modus vollständig entfernt werden muss.
Emulatoren starten
Sie sollten die Emulatoren starten, bevor Sie die Flutter-App starten. Starten Sie zuerst die Emulatoren, indem Sie im Terminal Folgendes ausführen:
firebase emulators:start
Dieser Befehl startet die Emulatoren und macht localhost-Ports verfügbar, mit denen wir mit ihnen interagieren können. Wenn Sie diesen Befehl ausführen, sollte die Ausgabe in etwa so aussehen:
Diese Ausgabe gibt Aufschluss darüber, welche Emulatoren ausgeführt werden und wo Sie sie finden. Sehen Sie sich zuerst die Benutzeroberfläche des Emulators unter localhost:4000
an.
Dies ist die Startseite der Benutzeroberfläche des lokalen Emulators. Hier werden alle verfügbaren Emulatoren mit dem Status „An“ oder „Aus“ aufgeführt.
5. Firebase Auth-Emulator
Der erste Emulator, den Sie verwenden, ist der Authentication-Emulator. Klicken Sie auf der Karte „Authentifizierung“ in der Benutzeroberfläche auf „Zum Emulator“. Daraufhin wird eine Seite wie diese angezeigt:
Diese Seite ähnelt der Seite der Auth-Webkonsole. Sie enthält eine Tabelle, in der die Nutzer aufgelistet sind, z. B. in der Onlinekonsole, und Sie können Nutzer manuell hinzufügen. Ein großer Unterschied besteht darin, dass die einzige Authentifizierungsmethode, die auf den Emulatoren verfügbar ist, per E-Mail und Passwort erfolgt. Das ist für die lokale Entwicklung ausreichend.
Als Nächstes fügen Sie dem Firebase Auth-Emulator einen Nutzer hinzu und melden ihn dann über die Flutter-UI an.
Nutzer hinzufügen
Klicken Sie auf die Schaltfläche „Nutzer hinzufügen“ und füllen Sie das Formular mit den folgenden Informationen aus:
- Anzeigename: Bindestrich
- E-Mail: dash@email.com
- Passwort: Dashboard
Senden Sie das Formular. Sie sehen, dass die Tabelle nun einen Nutzer enthält. Jetzt können Sie den Code aktualisieren, um sich mit diesem Nutzer anzumelden.
logged_out_view.dart
Der einzige Code im LoggedOutView
-Widget, der aktualisiert werden muss, befindet sich im Callback, der ausgelöst wird, wenn ein Nutzer auf die Anmeldeschaltfläche klickt. Aktualisieren Sie den Code so:
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'), ), ), ], ), ), ); } }
Im aktualisierten Code werden die Strings TODO
durch die E-Mail-Adresse und das Passwort ersetzt, die Sie im Authentifizierungsemulator erstellt haben. In der nächsten Zeile wurde die Zeile if(true)
durch Code ersetzt, der prüft, ob state.user
null ist. Der Code in AppClass
verdeutlicht dies.
app_state.dart
Zwei Teile des Codes in AppState
müssen aktualisiert werden. Weisen Sie dem Klassenmitglied „AppState.user“ zuerst den Typ User
aus dem Paket firebase_auth
zu, anstatt den Typ Object
.
Füllen Sie als Nächstes 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 den Nutzer lautet jetzt User?
. Diese User
-Klasse stammt aus Firebase Auth und stellt erforderliche Informationen wie User.displayName
bereit, auf die später eingegangen wird.
Dies ist der grundlegende Code, der erforderlich ist, um einen Nutzer mit einer E-Mail-Adresse und einem Passwort in Firebase Auth anzumelden. Es wird eine FirebaseAuth-Aufruf zur Anmeldung ausgeführt, die ein Future<UserCredential>
-Objekt zurückgibt. Wenn der Future abgeschlossen ist, prüft dieser Code, ob ein User
an UserCredential
angehängt ist. Wenn sich ein Nutzer im Anmeldedatenobjekt befindet, hat sich ein Nutzer erfolgreich angemeldet und die Property AppState.user
kann festgelegt werden. Wenn nicht, ist ein Fehler aufgetreten und der Fehler wird ausgegeben.
Die einzige Codezeile in dieser Methode, die speziell für diese App und nicht für allgemeinen FirebaseAuth-Code ist, ist der Aufruf der Methode _listenForEntries
. Diese wird im nächsten Schritt behandelt.
TODO: Aktionssymbol: Laden Sie die App neu und drücken Sie dann auf die Anmeldeschaltfläche, wenn sie angezeigt wird. Dadurch wird in der App eine Seite mit der Überschrift „Willkommen zurück, Person!“ geöffnet. Die Authentifizierung muss funktionieren, da Sie diese Seite aufrufen konnten. Es muss jedoch eine kleine Änderung an logged_in_view.dart
vorgenommen werden, damit der tatsächliche Name des Nutzers angezeigt wird.
logged_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 die displayName
aus der User
-Property des AppState
-Objekts ab. Diese displayName
wurde im Emulator festgelegt, als Sie Ihren ersten Nutzer definiert haben. Wenn Sie sich in Ihrer App anmelden, sollte jetzt „Willkommen zurück, Dash!“ und nicht mehr TODO
angezeigt werden.
6. Daten im Firestore-Emulator lesen und schreiben
Sehen Sie sich zuerst den Firestore-Emulator an. Klicken Sie auf der Startseite der Emulator-Benutzeroberfläche (localhost:4000
) auf der Karte „Firestore“ auf „Zum Emulator“. Das sollte so aussehen:
Emulator:
Firebase Console:
Wenn Sie bereits Erfahrung mit Firestore haben, werden Sie feststellen, dass diese Seite der Firestore-Seite der Firebase Console ähnelt. Es gibt jedoch einige nennenswerte Unterschiede.
- Sie können alle Daten mit nur einem Tastendruck löschen. Das wäre bei Produktionsdaten gefährlich, aber hilfreich für eine schnelle Iteration. Wenn Sie an einem neuen Projekt arbeiten und sich Ihr Datenmodell ändert, ist es einfach, dieses zu bereinigen.
- Es gibt einen Tab „Anfragen“. Auf diesem Tab können Sie eingehende Anfragen an diesen Emulator beobachten. Auf diesen Tab werde ich gleich noch genauer eingehen.
- Es gibt keine Registerkarten für Regeln, Indexe oder Nutzung. Es gibt ein Tool (im nächsten Abschnitt beschrieben), mit dem Sie Sicherheitsregeln schreiben können. Sie können jedoch keine Sicherheitsregeln für den lokalen Emulator festlegen.
Zusammenfassend lässt sich sagen, dass diese Version von Firestore mehr Tools bietet, die während der Entwicklung nützlich sind, und Tools, die in der Produktion benötigt werden, entfernt.
In Firestore schreiben
Bevor wir uns mit dem Tab „Anfragen“ im Emulator befassen, senden Sie eine Anfrage. Dazu sind Codeupdates erforderlich. Verbinden Sie zuerst das Formular in der App, um ein neues Tagebuch Entry
in Firestore zu schreiben.
So reichen Sie eine Entry
ein:
- Nutzer füllt das Formular aus und drückt die Schaltfläche
Submit
- Die Benutzeroberfläche ruft
AppState.writeEntryToFirebase
auf. AppState.writeEntryToFirebase
fügt Firebase einen Eintrag hinzu
Der Code in Schritt 1 oder 2 muss nicht geändert werden. Der einzige Code, der für Schritt 3 hinzugefügt werden muss, wird in der Klasse AppState
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 Methode „writeEntryToFirebase“ ruft eine Referenz auf die Sammlung „Entries“ in Firestore ab. Es wird dann ein neuer Eintrag hinzugefügt, der vom Typ Map<String, String>
sein muss.
In diesem Fall gab es die Sammlung „Einträge“ in Firestore nicht, daher wurde sie von Firestore erstellt.
Nachdem Sie diesen Code hinzugefügt haben, laden Sie Ihre App per Hot Reload neu oder starten Sie sie neu, melden Sie sich an und rufen Sie die Ansicht EntryForm
auf. Sie können das Formular mit einer beliebigen Strings
ausfüllen. Das Feld „Datum“ akzeptiert jeden String, da es für dieses Codelab vereinfacht wurde. Es gibt keine strenge Validierung und DateTime
-Objekte werden nicht berücksichtigt.)
Klicken Sie im Formular auf „Senden“. In der App passiert nichts, aber Sie können den neuen Eintrag in der Emulator-Benutzeroberfläche sehen.
Tab „Anfragen“ im Firestore-Emulator
Rufen Sie in der Benutzeroberfläche den Firestore-Emulator auf und sehen Sie sich den Tab „Daten“ an. Sie sollten jetzt eine Sammlung namens „Einträge“ im Stammverzeichnis Ihrer Datenbank sehen. Dieses sollte ein Dokument enthalten, das dieselben Informationen enthält, die Sie in das Formular eingegeben haben.
Das bestätigt, dass der AppState.writeEntryToFirestore
funktioniert hat. Sie können sich die Anfrage jetzt auf dem Tab „Anfragen“ genauer ansehen. Klicken Sie jetzt auf diesen Tab.
Firestore-Emulatoranfragen
Sie sollten eine Liste sehen, die in etwa so aussieht:
Sie können auf einen der Listeneinträge klicken, um sich hilfreiche Informationen anzusehen. Klicken Sie auf den CREATE
-Listeneintrag, der Ihrer Anfrage entspricht, um einen neuen Journaleintrag zu erstellen. Daraufhin wird eine neue Tabelle angezeigt, die so aussieht:
Wie bereits erwähnt, bietet der Firestore-Emulator Tools zum Entwickeln der Sicherheitsregeln Ihrer Anwendung. In dieser Ansicht sehen Sie genau, welche Zeile in Ihren Sicherheitsregeln diese Anfrage bestanden (oder fehlgeschlagen ist, falls dies der Fall war). In einer robusteren App können Sicherheitsregeln erweitert werden und mehrere Autorisierungsüberprüfungen umfassen. Diese Ansicht wird zum Schreiben und Debuggen dieser Autorisierungsregeln verwendet.
Außerdem können Sie damit ganz einfach alle Teile dieser Anfrage prüfen, einschließlich der Metadaten und der Authentifizierungsdaten. Diese Daten werden zum Schreiben komplexer Autorisierungsregeln verwendet.
Aus Firestore lesen
Firestore nutzt die Datensynchronisierung, um aktualisierte Daten per Push an verbundene Geräte zu übertragen. In Flutter-Code können Sie Firestore-Sammlungen und ‑Dokumente abhören (oder abonnieren). Ihr Code wird dann jedes Mal benachrichtigt, wenn sich Daten ändern. In dieser Anwendung wird mit der Methode AppState._listenForEntries
auf Firestore-Aktualisierungen gewartet.
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 in der Benutzeroberfläche, der zum Anzeigen der Daten aus Firestore erforderlich ist.
Aktualisieren Sie die _listenForEntries
-Methode so, dass sie dem Code unten entspricht:
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 „Einträge“ in Firestore. Wenn Firestore diesen Client benachrichtigt, dass neue Daten vorhanden sind, werden diese Daten übergeben und der Code in _listenForEntries
ändert alle untergeordneten Dokumente in ein Objekt, das unsere App verwenden kann (Entry
). Anschließend fügt es diese Einträge dem StreamController
namens _entriesStreamController
hinzu, das von der UI überwacht wird. Dieser Code ist das einzige erforderliche Update.
Denken Sie daran, dass die Methode AppState.logIn
_listenForEntries
aufruft, wodurch der Überwachungsprozess nach der Anmeldung eines Nutzers gestartet wird.
// ... 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 die App jetzt aus. Sie sollte so aussehen:
7. Daten in den Emulator exportieren und importieren
Firebase-Emulatoren unterstützen das Importieren und Exportieren von Daten. Wenn Sie die Importe und Exporte verwenden, können Sie die Entwicklung mit denselben Daten fortsetzen, wenn Sie eine Pause einlegen und die Entwicklung fortsetzen. Sie können auch Datendateien in Git committen, damit andere Entwickler, mit denen Sie zusammenarbeiten, dieselben Daten verwenden können.
Emulatordaten exportieren
Exportieren Sie zunächst die Emulatordaten, die Sie bereits haben. Öffnen Sie ein neues Terminalfenster und geben Sie den folgenden Befehl ein, während die Emulatoren noch ausgeführt werden:
firebase emulators:export ./emulators_data
.emulators_data
ist ein Argument, das Firebase angibt, wohin die Daten exportiert werden sollen. Wenn das Verzeichnis nicht vorhanden ist, wird es erstellt. Sie können einen beliebigen Namen für dieses Verzeichnis verwenden.
Wenn Sie diesen Befehl ausführen, wird im Terminal, in dem Sie den Befehl ausgeführt haben, diese Ausgabe angezeigt:
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
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.
Im Projektverzeichnis sollte außerdem ein Verzeichnis namens ./emulators_data
angezeigt werden, das unter anderem 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 weitermachen, wo Sie aufgehört haben.
Beenden Sie zuerst die Emulatoren, sofern sie ausgeführt werden. Drücken Sie dazu in Ihrem Terminal CTRL+C
.
Führen Sie als Nächstes den Befehl emulators:start
aus, den Sie bereits kennen, aber mit einem Flag, das angibt, welche Daten importiert werden sollen:
firebase emulators:start --import ./emulators_data
Wenn die Emulatoren gestartet sind, rufen Sie die Emulator-Benutzeroberfläche unter localhost:4000
auf. Dort sollten dieselben Daten angezeigt werden, mit denen Sie zuvor gearbeitet haben.
Daten beim Schließen von Emulatoren automatisch exportieren
Du kannst Daten auch automatisch exportieren, wenn du die Emulatoren beendest, anstatt daran zu denken, die Daten am Ende jeder Entwicklungssitzung zu exportieren.
Führen Sie beim Starten der Emulatoren den Befehl emulators:start
mit zwei zusätzlichen Flags aus.
firebase emulators:start --import ./emulators_data --export-on-exit
Voilà! Ihre Daten werden jetzt jedes Mal gespeichert und neu geladen, wenn Sie mit den Emulatoren für dieses Projekt arbeiten. Sie können auch ein anderes Verzeichnis als Argument für –export-on-exit flag
angeben. Standardmäßig wird jedoch das Verzeichnis verwendet, das an –import
übergeben wird.
Sie können auch eine Kombination dieser Optionen verwenden. Hinweis aus der Dokumentation: 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, z. B. firebase emulators:start --import=./data-path --export-on-exit
. Übergeben Sie schließlich bei Bedarf verschiedene Verzeichnispfade an die Flags --import
und --export-on-exit
.
8. Glückwunsch!
Sie haben „Einrichtung und Ausführung mit dem Firebase-Emulator und Flutter“ abgeschlossen. Den vollständigen Code für dieses Codelab finden Sie im Verzeichnis „complete“ auf GitHub: Flutter Codelabs
Behandelte Themen
- Flutter-App zur Verwendung von Firebase einrichten
- Firebase-Projekt einrichten
- FlutterFire-CLI
- Firebase CLI
- Firebase Authentication-Emulator
- Firebase Firestore-Emulator
- Emulatordaten importieren und exportieren
Nächste Schritte
- Weitere Informationen zur Verwendung von Firestore und Authentifizierung in Flutter: Codelab zu Firebase für Flutter
- Weitere Firebase-Tools mit Emulatoren:
- Cloud Storage
- Cloud Functions
- Realtime Database
- Entdecken Sie die FlutterFire-UI, mit der Sie Ihrer App schnell eine Google-Authentifizierung hinzufügen können.
Weitere Informationen
- Firebase-Website: firebase.google.com
- Flutter-Website: flutter.dev
- FlutterFire Firebase-Flutter-Widgets: firebase.flutter.dev
- YouTube-Kanal von Firebase
- YouTube-Kanal von Flutter
Sparky ist stolz auf dich!