1. Prima di iniziare
In questo codelab, imparerai a utilizzare Firebase Emulator Suite con Flutter durante lo sviluppo locale. Imparerai a utilizzare l'autenticazione tramite email e password tramite Emulator Suite e a leggere e scrivere dati nell'emulatore Firestore. Infine, imparerai a importare ed esportare dati dagli emulatori, in modo da lavorare con gli stessi dati falsi ogni volta che torni allo sviluppo.
Prerequisiti
Questo codelab presuppone che tu abbia una certa esperienza con Flutter. In caso contrario, ti consigliamo di imparare prima le nozioni di base. I seguenti link sono utili:
- Fai un tour del framework dei widget Flutter
- Prova il codelab Scrivi la tua prima app Flutter, parte 1
Dovresti anche avere un po' di esperienza con Firebase, ma non importa se non hai mai aggiunto Firebase a un progetto Flutter. Se non hai familiarità con la console Firebase o non hai mai utilizzato Firebase, consulta prima i seguenti link:
Cosa creerai
Questo codelab ti guida nella creazione di una semplice applicazione di journaling. L'applicazione avrà una schermata di accesso e una schermata che ti consente di leggere le voci del diario passate e di crearne di nuove.
Obiettivi didattici
Imparerai a iniziare a utilizzare Firebase e a integrare e utilizzare Firebase Emulator Suite nel tuo flusso di lavoro di sviluppo Flutter. Verranno trattati i seguenti argomenti di Firebase:
Tieni presente che questi argomenti vengono trattati nella misura in cui sono necessari per coprire la suite di emulatori Firebase. Questo codelab si concentra sull'aggiunta di un progetto Firebase alla tua app Flutter e sullo sviluppo utilizzando Firebase Emulator Suite. Non ci saranno discussioni approfondite su Firebase Authentication o Firestore. Se non hai familiarità con questi argomenti, ti consigliamo di iniziare con il codelab Getting to Know Firebase for Flutter.
Che cosa ti serve
- Conoscenza pratica di Flutter e dell'SDK installato
- Editor di testo IntelliJ JetBrains o VS Code
- Browser Google Chrome (o un altro target di sviluppo preferito per Flutter). Alcuni comandi del terminale in questo codelab presuppongono che tu stia eseguendo l'app su Chrome)
2. Crea e configura un progetto Firebase
La prima attività da completare è la creazione di un progetto Firebase nella console web di Firebase. La maggior parte di questo codelab si concentrerà su Emulator Suite, che utilizza un'interfaccia utente in esecuzione locale, ma devi prima configurare un progetto Firebase completo.
Crea un progetto Firebase
- Accedi alla console Firebase utilizzando il tuo Account Google.
- Fai clic sul pulsante per creare un nuovo progetto, quindi inserisci un nome per il progetto (ad esempio
Firebase-Flutter-Codelab
).
- Fai clic su Continua.
- Se richiesto, leggi e accetta i termini di Firebase, quindi fai clic su Continua.
- (Facoltativo) Attiva l'assistenza AI nella console Firebase (denominata "Gemini in Firebase").
- Per questo codelab non hai bisogno di Google Analytics, quindi disattiva l'opzione Google Analytics.
- Fai clic su Crea progetto, attendi il provisioning del progetto, poi fai clic su Continua.
Per saperne di più sui progetti Firebase, consulta Informazioni sui progetti Firebase.
Configura i prodotti Firebase
L'app che stai creando utilizza due prodotti Firebase disponibili per le app Flutter:
- Firebase Authentication per consentire agli utenti di accedere alla tua app.
- Cloud Firestore per salvare dati strutturati sul cloud e ricevere una notifica immediata quando i dati cambiano.
Questi due prodotti richiedono una configurazione speciale o devono essere attivati utilizzando la Console Firebase.
Attiva Cloud Firestore
L'app Flutter utilizza Cloud Firestore per salvare le voci del diario.
Abilita Cloud Firestore:
- Nella sezione Build della console Firebase, fai clic su Cloud Firestore.
- Fai clic su Crea database.
- Seleziona l'opzione Avvia in modalità di test. Leggi l'esclusione di responsabilità relativa alle regole di sicurezza. La modalità di test ti consente di scrivere liberamente nel database durante lo sviluppo. Fai clic su Avanti.
- Seleziona la posizione per il tuo database (puoi utilizzare quella predefinita). Tieni presente che questa località non potrà essere modificata in un secondo momento.
- Fai clic su Abilita.
3. Configurare l'app Flutter
Prima di iniziare, devi scaricare il codice iniziale e installare l'interfaccia a riga di comando di Firebase.
Recupera il codice di avvio
Clona il repository GitHub dalla riga di comando:
git clone https://github.com/flutter/codelabs.git flutter-codelabs
In alternativa, se hai installato lo strumento GitHub CLI:
gh repo clone flutter/codelabs flutter-codelabs
Il codice di esempio deve essere clonato nella directory flutter-codelabs
, che contiene il codice per una raccolta di codelab. Il codice per questo codelab si trova in flutter-codelabs/firebase-emulator-suite
.
La struttura delle directory in flutter-codelabs/firebase-emulator-suite
è costituita da due progetti Flutter. Uno si chiama complete
, che puoi consultare se vuoi andare avanti o fare un riferimento incrociato al tuo codice. L'altro progetto si chiama start
.
Il codice con cui vuoi iniziare si trova nella directory flutter-codelabs/firebase-emulator-suite/start
. Apri o importa la directory nell'IDE che preferisci.
cd flutter-codelabs/firebase-emulator-suite/start
Installa l'interfaccia a riga di comando di Firebase
La CLI Firebase fornisce strumenti per la gestione dei tuoi progetti Firebase. L'interfaccia a riga di comando è necessaria per utilizzare Emulator Suite, quindi dovrai installarla.
Esistono diversi modi per installare la CLI. Il modo più semplice, se utilizzi macOS o Linux, è eseguire questo comando dal terminale:
curl -sL https://firebase.tools | bash
Dopo aver installato la CLI, devi eseguire l'autenticazione con Firebase.
- Accedi a Firebase utilizzando il tuo Account Google eseguendo questo comando:
firebase login
- Questo comando connette la tua macchina locale a Firebase e ti concede l'accesso ai tuoi progetti Firebase.
- Verifica che la CLI sia installata correttamente e abbia accesso al tuo account elencando i tuoi progetti Firebase. Esegui questo comando:
firebase projects:list
- L'elenco visualizzato deve essere uguale a quello dei progetti Firebase elencati nella console Firebase. Dovresti visualizzare almeno firebase-flutter-codelab.
Installa l'interfaccia a riga di comando FlutterFire
L'interfaccia a riga di comando FlutterFire è basata sull'interfaccia a riga di comando di Firebase e semplifica l'integrazione di un progetto Firebase con la tua app Flutter.
Innanzitutto, installa l'interfaccia a riga di comando:
dart pub global activate flutterfire_cli
Assicurati che la CLI sia stata installata. Esegui il seguente comando nella directory del progetto Flutter e assicurati che la CLI restituisca il menu di aiuto.
flutterfire --help
Utilizza l'interfaccia a riga di comando di Firebase e l'interfaccia a riga di comando FlutterFire per aggiungere il tuo progetto Firebase alla tua app Flutter
Con le due CLI installate, puoi configurare singoli prodotti Firebase (come Firestore), scaricare gli emulatori e aggiungere Firebase alla tua app Flutter con un paio di comandi del terminale.
Innanzitutto, completa la configurazione di Firebase eseguendo questo comando:
firebase init
Questo comando ti guiderà attraverso una serie di domande necessarie per configurare il progetto. Questi screenshot mostrano il flusso:
- Quando ti viene chiesto di selezionare le funzionalità, seleziona "Firestore" ed "Emulatori". Non è presente un'opzione di autenticazione, in quanto non utilizza una configurazione modificabile dai file di progetto Flutter.
- Successivamente, seleziona "Utilizza un progetto esistente" quando richiesto.
- Ora seleziona il progetto che hai creato in un passaggio precedente: flutter-firebase-codelab.
- Successivamente, ti verrà posta una serie di domande sulla denominazione dei file che verranno generati. Ti suggerisco di premere "Invio" per ogni domanda per selezionare il valore predefinito.
- Infine, dovrai configurare gli emulatori. Seleziona Firestore e Authentication dall'elenco, poi premi "Invio" per ogni domanda sulle porte specifiche da utilizzare per ogni emulatore. Quando ti viene chiesto se vuoi utilizzare l'interfaccia utente dell'emulatore, devi selezionare l'opzione predefinita, ovvero Sì.
Al termine della procedura, dovresti vedere un output simile allo screenshot seguente.
Importante: l'output potrebbe essere leggermente diverso dal mio, come mostrato nello screenshot di seguito, perché l'ultima domanda sarà impostata su "No" per impostazione predefinita se hai già scaricato gli emulatori.
Configura FlutterFire
Dopodiché, puoi utilizzare FlutterFire per generare il codice Dart necessario per utilizzare Firebase nella tua app Flutter.
flutterfire configure
Quando viene eseguito questo comando, ti verrà chiesto di selezionare il progetto Firebase che vuoi utilizzare e le piattaforme che vuoi configurare. In questo codelab, gli esempi utilizzano Flutter Web, ma puoi configurare il progetto Firebase in modo che utilizzi tutte le opzioni.
Gli screenshot seguenti mostrano le richieste a cui dovrai rispondere.
Questo screenshot mostra l'output alla fine del processo. Se hai familiarità con Firebase, noterai che non hai dovuto creare applicazioni nella console e che l'interfaccia a riga di comando di FlutterFire lo ha fatto per te.
Aggiungi pacchetti Firebase all'app Flutter
L'ultimo passaggio della configurazione consiste nell'aggiungere i pacchetti Firebase pertinenti al tuo progetto Flutter. Nel terminale, assicurati di trovarti nella directory principale del progetto Flutter in flutter-codelabs/firebase-emulator-suite/start
. Quindi, esegui i tre comandi seguenti:
flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add cloud_firestore
Questi sono gli unici pacchetti che utilizzerai in questa applicazione.
4. Abilitazione degli emulatori Firebase
Finora, l'app Flutter e il progetto Firebase sono configurati per poter utilizzare gli emulatori, ma devi comunque indicare al codice Flutter di reindirizzare le richieste Firebase in uscita alle porte locali.
Innanzitutto, aggiungi il codice di inizializzazione di Firebase e il codice di configurazione dell'emulatore alla funzione 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()); }
Le prime righe di codice inizializzano Firebase. Quasi sempre, se utilizzi Firebase in un'app Flutter, devi iniziare chiamando WidgetsFlutterBinding.ensureInitialized
e Firebase.initializeApp
.
Successivamente, il codice che inizia con la riga if (kDebugMode)
indica alla tua app di scegliere come target gli emulatori anziché un progetto Firebase di produzione. kDebugMode
garantisce che il targeting degli emulatori avvenga solo se ti trovi in un ambiente di sviluppo. Poiché kDebugMode
è un valore costante, il compilatore Dart sa di rimuovere completamente il blocco di codice in modalità di rilascio.
Avvia gli emulatori
Devi avviare gli emulatori prima di avviare l'app Flutter. Per prima cosa, avvia gli emulatori eseguendo questo comando nel terminale:
firebase emulators:start
Questo comando avvia gli emulatori ed espone le porte localhost con cui possiamo interagire. Quando esegui questo comando, dovresti visualizzare un output simile a questo:
Questo output indica quali emulatori sono in esecuzione e dove puoi visualizzarli. Per prima cosa, dai un'occhiata alla UI dell'emulatore all'indirizzo localhost:4000
.
Questa è la home page della UI dell'emulatore locale. Elenca tutti gli emulatori disponibili e ciascuno è etichettato con lo stato attivo o disattivato.
5. L'emulatore Firebase Auth
Il primo emulatore che utilizzerai è l'emulatore di autenticazione. Inizia con l'emulatore di autenticazione facendo clic su "Vai all'emulatore" nella scheda Autenticazione nell'interfaccia utente. Vedrai una pagina simile a questa:
Questa pagina presenta delle somiglianze con la pagina della console web Auth. Contiene una tabella che elenca gli utenti come la console online e ti consente di aggiungerli manualmente. Una grande differenza è che l'unica opzione di metodo di autenticazione disponibile sugli emulatori è tramite email e password. È sufficiente per lo sviluppo locale.
Successivamente, esamineremo la procedura per aggiungere un utente all'emulatore Firebase Auth e poi accedere con questo utente tramite la UI di Flutter.
Aggiungere un utente
Fai clic sul pulsante "Aggiungi utente" e compila il modulo con queste informazioni:
- Nome visualizzato: Dash
- Email: dash@email.com
- Password: dashword
Invia il modulo e vedrai che la tabella ora include un utente. Ora puoi aggiornare il codice per accedere con questo utente.
logged_out_view.dart
L'unico codice nel widget LoggedOutView
che deve essere aggiornato si trova nel callback attivato quando un utente preme il pulsante di accesso. Aggiorna il codice in modo che abbia questo aspetto:
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'), ), ), ], ), ), ); } }
Il codice aggiornato sostituisce le stringhe TODO
con l'email e la password che hai creato nell'emulatore di autenticazione. Nella riga successiva, la riga if(true)
è stata sostituita da un codice che verifica se state.user
è null. Il codice in AppClass
fa più luce su questo aspetto.
app_state.dart
Devono essere aggiornate due parti del codice in AppState
. Innanzitutto, assegna al membro della classe AppState.user il tipo User
dal pacchetto firebase_auth
, anziché il tipo Object
.
Secondo, compila il metodo AppState.login
come mostrato di seguito:
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!'); } } // ... }
La definizione del tipo per l'utente ora è User?
. La classe User
proviene da Firebase Auth e fornisce le informazioni necessarie, ad esempio User.displayName
, di cui parleremo tra poco.
Questo è il codice di base necessario per accedere a un utente con un indirizzo email e una password in Firebase Auth. Chiama FirebaseAuth per accedere, che restituisce un oggetto Future<UserCredential>
. Al termine del futuro, questo codice controlla se è presente un User
allegato a UserCredential
. Se è presente un utente nell'oggetto credenziale, significa che l'utente ha eseguito l'accesso correttamente e la proprietà AppState.user
può essere impostata. In caso contrario, si è verificato un errore e viene stampato.
Tieni presente che l'unica riga di codice in questo metodo specifica per questa app (anziché il codice FirebaseAuth generale) è la chiamata al metodo _listenForEntries
, che verrà trattato nel passaggio successivo.
TODO: Action Icon – Reload your app, and then press the Login button when it renders. In questo modo l'app passa a una pagina con il messaggio "Bentornato, [nome della persona]" in alto. L'autenticazione deve funzionare, perché ti ha consentito di accedere a questa pagina, ma è necessario apportare un aggiornamento minore a logged_in_view.dart
per visualizzare il nome effettivo dell'utente.
logged_in_view.dart
Modifica la prima riga nel metodo LoggedInView.build
:
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( // ...
Ora, questa riga recupera displayName
dalla proprietà User
dell'oggetto AppState
. Questo displayName
è stato impostato nell'emulatore quando hai definito il primo utente. Ora, quando accedi all'app, dovrebbe essere visualizzato il messaggio "Bentornato, Dash!" anziché TODO
.
6. Leggi e scrivi dati nell'emulatore Firestore
Per prima cosa, dai un'occhiata all'emulatore Firestore. Nella home page dell'interfaccia utente dell'emulatore (localhost:4000
), fai clic su "Vai all'emulatore" nella scheda Firestore. Dovrebbe avere il seguente aspetto:
Emulatore:
Console Firebase:
Se hai esperienza con Firestore, noterai che questa pagina è simile alla pagina Firestore della console Firebase. Tuttavia, ci sono alcune differenze notevoli.
- Puoi cancellare tutti i dati con un solo tocco di un pulsante. Sarebbe pericoloso con i dati di produzione, ma è utile per un'iterazione rapida. Se stai lavorando a un nuovo progetto e il modello di dati cambia, è facile cancellarlo.
- È presente una scheda "Richieste". Questa scheda ti consente di osservare le richieste in arrivo effettuate a questo emulatore. Parleremo di questa scheda in modo più dettagliato tra poco.
- Non sono presenti schede per Regole, Indici o Utilizzo. Esiste uno strumento (descritto nella sezione successiva) che aiuta a scrivere regole di sicurezza, ma non puoi impostare regole di sicurezza per l'emulatore locale.
Per riassumere l'elenco, questa versione di Firestore fornisce più strumenti utili durante lo sviluppo e rimuove quelli necessari in produzione.
Scrivi in Firestore
Prima di parlare della scheda "Richieste" nell'emulatore, effettua una richiesta. Ciò richiede aggiornamenti del codice. Inizia collegando il modulo nell'app per scrivere una nuova voce del diario Entry
in Firestore.
Il flusso generale per inviare un Entry
è il seguente:
- L'utente compila il modulo e preme il pulsante
Submit
- L'interfaccia utente chiama
AppState.writeEntryToFirebase
AppState.writeEntryToFirebase
aggiunge una voce a Firebase
Nessuna parte del codice coinvolta nel passaggio 1 o 2 deve essere modificata. L'unico codice da aggiungere per il passaggio 3 verrà aggiunto nella classe AppState
. Apporta la seguente modifica a AppState.writeEntryToFirebase
.
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, }); } // ... }
Il codice nel metodo writeEntryToFirebase recupera un riferimento alla raccolta denominata "Entries" in Firestore. Aggiunge quindi una nuova voce, che deve essere di tipo Map<String, String>
.
In questo caso, la raccolta "Entries" in Firestore non esisteva, quindi Firestore ne ha creata una.
Dopo aver aggiunto il codice, ricarica a caldo o riavvia l'app, accedi e vai alla visualizzazione EntryForm
. Puoi compilare il modulo con i Strings
che preferisci. Il campo Data accetta qualsiasi stringa, in quanto è stato semplificato per questo codelab. Non ha una convalida rigorosa e non si preoccupa in alcun modo degli oggetti DateTime
.)
Premi Invia sul modulo. Non succederà nulla nell'app, ma potrai vedere la nuova voce nell'interfaccia utente dell'emulatore.
La scheda Richieste nell'emulatore Firestore
Nella UI, vai all'emulatore Firestore e guarda la scheda "Dati". Dovresti vedere che ora esiste una raccolta alla radice del database chiamata "Entries". Dovresti trovare un documento contenente le stesse informazioni che hai inserito nel modulo.
Ciò conferma che l'elemento AppState.writeEntryToFirestore
ha funzionato e ora puoi esplorare ulteriormente la richiesta nella scheda Richieste. Fai clic su questa scheda.
Richieste dell'emulatore Firestore
Qui dovresti vedere un elenco simile a questo:
Puoi fare clic su uno qualsiasi di questi elementi dell'elenco e visualizzare molte informazioni utili. Fai clic sulla voce di elenco CREATE
corrispondente alla tua richiesta per creare una nuova voce di diario. Vedrai una nuova tabella simile alla seguente:
Come accennato, l'emulatore Firestore fornisce strumenti per sviluppare le regole di sicurezza della tua app. Questa visualizzazione mostra esattamente la riga delle regole di sicurezza superata (o non superata, se è questo il caso) dalla richiesta. In un'app più solida, le regole di sicurezza possono crescere e avere più controlli di autorizzazione. Questa visualizzazione viene utilizzata per scrivere ed eseguire il debug di queste regole di autorizzazione.
Fornisce inoltre un modo semplice per esaminare ogni parte di questa richiesta, inclusi i metadati e i dati di autenticazione. Questi dati vengono utilizzati per scrivere regole di autorizzazione complesse.
Lettura da Firestore
Firestore utilizza la sincronizzazione per inviare i dati aggiornati ai dispositivi connessi. Nel codice Flutter, puoi ascoltare (o abbonarti) a raccolte e documenti Firestore e il tuo codice riceverà una notifica ogni volta che i dati cambiano. In questa app, l'ascolto degli aggiornamenti di Firestore viene eseguito nel metodo denominato AppState._listenForEntries
.
Questo codice funziona in combinazione con StreamController
e Stream
chiamati rispettivamente AppState._entriesStreamController
e AppState.entries
. Il codice è già scritto, così come tutto il codice necessario nell'interfaccia utente per visualizzare i dati di Firestore.
Aggiorna il metodo _listenForEntries
in modo che corrisponda al codice riportato di seguito:
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); }); } // ... }
Questo codice ascolta la raccolta "Entries" in Firestore. Quando Firestore comunica a questo client che sono presenti nuovi dati, li trasmette e il codice in _listenForEntries
trasforma tutti i documenti secondari in un oggetto che la nostra app può utilizzare (Entry
). Quindi, aggiunge queste voci a StreamController
chiamato _entriesStreamController
(che l'interfaccia utente sta ascoltando). Questo codice è l'unico aggiornamento richiesto.
Infine, ricorda che il metodo AppState.logIn
effettua una chiamata a _listenForEntries
, che inizia il processo di ascolto dopo che un utente ha eseguito l'accesso.
// ... 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!'); } } // ...
Ora esegui l'app. Dovrebbe avere il seguente aspetto:
7. Esportare e importare i dati nell'emulatore
Gli emulatori Firebase supportano l'importazione e l'esportazione dei dati. L'utilizzo delle importazioni e delle esportazioni ti consente di continuare lo sviluppo con gli stessi dati quando fai una pausa e poi riprendi. Puoi anche eseguire il commit dei file di dati in Git e gli altri sviluppatori con cui collabori avranno gli stessi dati su cui lavorare.
Esportare i dati dell'emulatore
Innanzitutto, esporta i dati dell'emulatore che hai già. Mentre gli emulatori sono ancora in esecuzione, apri una nuova finestra del terminale ed esegui questo comando:
firebase emulators:export ./emulators_data
.emulators_data
è un argomento che indica a Firebase dove esportare i dati. Se la directory non esiste, viene creata. Puoi utilizzare il nome che preferisci per la directory.
Quando esegui questo comando, vedrai questo output nel terminale in cui l'hai eseguito:
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
Se passi alla finestra del terminale in cui sono in esecuzione gli emulatori, vedrai questo output:
i emulators: Received export request. Exporting data to /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data. ✔ emulators: Export complete.
Infine, se guardi nella directory del progetto, dovresti vedere una directory chiamata ./emulators_data
, che contiene file JSON
, tra gli altri file di metadati, con i dati che hai salvato.
Importare i dati dell'emulatore
Ora puoi importare questi dati nell'ambito del flusso di lavoro di sviluppo e riprendere da dove avevi interrotto.
Innanzitutto, interrompi gli emulatori se sono in esecuzione premendo CTRL+C
nel terminale.
Successivamente, esegui il comando emulators:start
che hai già visto, ma con un flag che indica i dati da importare:
firebase emulators:start --import ./emulators_data
Quando gli emulatori sono attivi, vai all'interfaccia utente dell'emulatore all'indirizzo localhost:4000
e dovresti visualizzare gli stessi dati con cui lavoravi in precedenza.
Esportare automaticamente i dati alla chiusura degli emulatori
Puoi anche esportare i dati automaticamente quando esci dagli emulatori, anziché ricordarti di esportarli al termine di ogni sessione di sviluppo.
Quando avvii gli emulatori, esegui il comando emulators:start
con due flag aggiuntivi.
firebase emulators:start --import ./emulators_data --export-on-exit
Voilà! I tuoi dati verranno ora salvati e ricaricati ogni volta che utilizzi gli emulatori per questo progetto. Puoi anche specificare una directory diversa come argomento di –export-on-exit flag
, ma per impostazione predefinita verrà utilizzata la directory passata a –import
.
Puoi anche utilizzare una qualsiasi combinazione di queste opzioni. Questa è la nota della documentazione: la directory di esportazione può essere specificata con questo flag: firebase emulators:start --export-on-exit=./saved-data
. Se viene utilizzato --import
, il percorso di esportazione è impostato sullo stesso valore; ad esempio: firebase emulators:start --import=./data-path --export-on-exit
. Infine, se vuoi, passa percorsi di directory diversi ai flag --import
e --export-on-exit
.
8. Complimenti!
Hai completato Inizia a utilizzare l'emulatore Firebase e Flutter. Puoi trovare il codice completato per questo codelab nella directory "complete" su GitHub: Flutter Codelabs
Argomenti trattati
- Configurazione di un'app Flutter per l'utilizzo di Firebase
- Configurazione di un progetto Firebase
- Interfaccia a riga di comando FlutterFire
- Interfaccia a riga di comando di Firebase
- Emulatore Firebase Authentication
- Emulatore Firebase Firestore
- Importazione ed esportazione dei dati dell'emulatore
Passaggi successivi
- Scopri di più sull'utilizzo di Firestore e Authentication in Flutter: Get to know Firebase for Flutter Codelab
- Esplora altri strumenti Firebase che offrono emulatori:
- Cloud Storage
- Cloud Functions
- Realtime Database
- Esplora FlutterFire UI per aggiungere rapidamente l'autenticazione Google alla tua app.
Scopri di più
- Sito Firebase: firebase.google.com
- Sito Flutter: flutter.dev
- Widget FlutterFire Firebase Flutter: firebase.flutter.dev
- Canale YouTube di Firebase
- Canale YouTube di Flutter
Sparky è orgoglioso di te.