1. Prima di iniziare
In questo codelab imparerai ad aggiungere Firebase Authentication alla tua app Flutter utilizzando il pacchetto FlutterFire UI. Con questo pacchetto, aggiungerai l'autenticazione email/password e l'autenticazione di Google Sign In a un'app Flutter. Scoprirai inoltre come configurare un progetto Firebase e utilizzare l'interfaccia a riga di comando FlutterFire per inizializzare Firebase nella tua app Flutter.
Prerequisiti
Questo codelab presuppone che tu abbia una certa esperienza con Flutter. In caso contrario, ti consigliamo di apprendere prima le nozioni di base. I seguenti link sono utili:
- Fai un tour del framework di widget di Flutter
- Prova il codelab Scrivi la tua prima app Flutter, parte 1
Dovresti anche avere una certa esperienza con Firebase, ma non preoccuparti se non hai mai aggiunto Firebase a un progetto Flutter. Se non hai dimestichezza con la Console Firebase o se non hai mai utilizzato Firebase, consulta prima i seguenti link:
Cosa creerai
Questo codelab ti guida nella creazione del flusso di autenticazione per un'app Flutter utilizzando Firebase per l'autenticazione. L'applicazione avrà una schermata di accesso, una schermata "Registrati", una schermata di recupero della password e una schermata del profilo utente.
Obiettivi didattici
Questo codelab illustra:
- Aggiunta di Firebase a un'app Flutter
- Configurazione della console Firebase
- Utilizzo dell'interfaccia a riga di comando di Firebase per aggiungere Firebase all'applicazione
- Utilizzo dell'interfaccia a riga di comando FlutterFire per generare la configurazione di Firebase in Dart
- Aggiunta di Firebase Authentication alla tua app Flutter
- Configurazione di Firebase Authentication nella console
- Aggiunta dell'accesso con email e password con il pacchetto
firebase_ui_auth
- Aggiunta della registrazione utente con il pacchetto
firebase_ui_auth
- Aggiunta di una pagina "Password dimenticata?"
- Aggiunta di Accedi con Google con
firebase_ui_auth
- Configurare l'app in modo che funzioni con più provider di accesso.
- Aggiunta di una schermata del profilo utente all'applicazione con il pacchetto
firebase_ui_auth
Questo codelab riguarda in modo specifico l'aggiunta di un sistema di autenticazione solido utilizzando il pacchetto firebase_ui_auth
. Come vedrai, l'intera app, con tutte le funzionalità sopra indicate, può essere implementata con circa 100 righe di codice.
Che cosa ti serve
- Conoscenza pratica di Flutter e dell'SDK installato
- Un editor di testo (IDE JetBrains, Android Studio e VS Code sono supportati da Flutter)
- 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 operazione da completare è creare un progetto Firebase nella console web di Firebase.
Crea un progetto Firebase
- Accedi a Firebase.
- Nella Console Firebase, fai clic su Aggiungi progetto (o Crea un progetto) e inserisci un nome per il progetto Firebase (ad esempio "FlutterFire-UI-Codelab").
- Fai clic sulle opzioni di creazione del progetto. Accetta i Termini di Firebase, se richiesto. Salta la configurazione di Google Analytics perché non utilizzerai Analytics per questa app.
Per scoprire di più sui progetti Firebase, consulta Informazioni sui progetti Firebase.
Attivare l'accesso con email per Firebase Authentication
L'app che stai creando utilizza Firebase Authentication per consentire agli utenti di accedere alla tua app. Consente inoltre ai nuovi utenti di registrarsi dall'applicazione Flutter.
Firebase Authentication deve essere attivata utilizzando la console Firebase e, una volta attivata, richiede una configurazione speciale.
Per consentire agli utenti di accedere all'app web, utilizza innanzitutto il metodo di accesso Email/password. In un secondo momento, aggiungerai il metodo Accedi con Google.
- Nella console Firebase, espandi il menu Build nel riquadro a sinistra.
- Fai clic su Autenticazione, poi sul pulsante Inizia e infine sulla scheda Metodo di accesso (o fai clic qui per andare direttamente alla scheda Metodo di accesso).
- Fai clic su Email/Password nell'elenco Provider di accesso, imposta l'opzione Attiva su On e poi fai clic su Salva.
3. Configurare l'app Flutter
Prima di iniziare, devi scaricare il codice di avvio e installare l'interfaccia a riga di comando di Firebase.
Ottieni 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 CLI di GitHub :
gh repo clone flutter/codelabs flutter-codelabs
Il codice di esempio deve essere clonato nella directory flutter-codelabs
del computer, che contiene il codice di una raccolta di codelab. Il codice di questo codelab si trova nella sottodirectory flutter-codelabs/firebase-auth-flutterfire-ui
.
La directory flutter-codelabs/firebase-auth-flutterfire-ui
contiene due progetti Flutter. Uno si chiama complete
e l'altro start
. La directory start
contiene un progetto incompleto ed è qui che passerai più tempo.
cd flutter-codelabs/firebase-auth-flutterfire-ui/start
Se vuoi andare avanti o vedere come dovrebbe apparire qualcosa al termine, cerca nella directory denominata completa per il riferimento incrociato.
Se vuoi seguire il codelab e aggiungere del codice, devi iniziare con l'app Flutter in flutter-codelabs/firebase-auth-flutterfire-ui/start
e aggiungere codice al progetto durante il codelab. Apri o importa la directory nell'IDE che preferisci.
Installa l'interfaccia a riga di comando di Firebase
L'interfaccia a riga di comando di Firebase fornisce strumenti per la gestione dei progetti Firebase. L'interfaccia a riga di comando è necessaria per l'interfaccia a riga di comando FlutterFire, che installerai a breve.
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 l'interfaccia a riga di comando, devi autenticarti con Firebase.
- Accedi a Firebase utilizzando il tuo Account Google eseguendo il seguente comando:
firebase login
- Questo comando connette il computer locale a Firebase e ti concede l'accesso ai tuoi progetti Firebase.
- Verifica che l'interfaccia a riga di comando sia installata correttamente e abbia accesso al tuo account elencando i tuoi progetti Firebase. Esegui questo comando:
firebase projects:list
- L'elenco visualizzato dovrebbe essere uguale a quello dei progetti Firebase elencati nella Console Firebase. Dovresti vedere almeno
flutterfire-ui-codelab.
Installa l'interfaccia a riga di comando FlutterFire
L'interfaccia a riga di comando FlutterFire è uno strumento che semplifica la procedura di installazione di Firebase su tutte le piattaforme supportate nella tua app Flutter. È basata sull'interfaccia a riga di comando di Firebase.
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 e assicurati che l'interfaccia a riga di comando mostri il menu di aiuto.
flutterfire -—help
Aggiungi il progetto Firebase all'app Flutter
Configurare FlutterFire
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.
Gli screenshot seguenti mostrano i prompt a cui dovrai rispondere.
- Seleziona il progetto che vuoi utilizzare. In questo caso, utilizza
flutterfire-ui-codelab
- Seleziona le piattaforme che vuoi utilizzare. In questo codelab sono descritti i passaggi per configurare Firebase Authentication per Flutter per web, iOS e Android, ma puoi configurare il tuo progetto Firebase in modo da utilizzare tutte le opzioni.
- Questo screenshot mostra l'output al termine del processo. Se hai dimestichezza con Firebase, noterai che non hai dovuto creare applicazioni di piattaforma (ad esempio un'applicazione per Android) nella console, ma che è stato FlutterFire CLI a farlo per te.
Al termine, controlla l'app Flutter nell'editor di testo. L'interfaccia a riga di comando FlutterFire ha generato un nuovo file denominato firebase_options.dart
. Questo file contiene una classe denominata FirebaseOptions, che ha variabili statiche che contengono la configurazione di Firebase necessaria per ogni piattaforma. Se hai selezionato tutte le piattaforme quando hai eseguito flutterfire configure
, vedrai valori statici denominati web
, android
, ios
e macos
.
firebase_options.dart
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
// ignore: missing_enum_constant_in_switch
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
}
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyCqFjCV_9CZmYeIvcK9FVy4drmKUlSaIWY',
appId: '1:963656261848:web:7219f7fca5fc70afb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
authDomain: 'flutterfire-ui-codelab.firebaseapp.com',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
measurementId: 'G-DGF0CP099H',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyDconZaCQpkxIJ5KQBF-3tEU0rxYsLkIe8',
appId: '1:963656261848:android:c939ccc86ab2dcdbb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
iosClientId: '963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com',
iosBundleId: 'com.example.complete',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
iosClientId: '963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com',
iosBundleId: 'com.example.complete',
);
}
Firebase utilizza la parola applicazione per fare riferimento a una build specifica per una piattaforma specifica in un progetto Firebase. Ad esempio, il progetto Firebase denominato FlutterFire-ui-codelab ha più applicazioni: una per Android, una per iOS, una per macOS e una per il web.
Il metodo DefaultFirebaseOptions.currentPlatform
utilizza l'enum TargetPlatform
esposto da Flutter per rilevare la piattaforma su cui è in esecuzione l'app e restituisce i valori di configurazione di Firebase necessari per l'applicazione Firebase corretta.
Aggiungere i pacchetti Firebase all'app Flutter
Il passaggio di configurazione finale consiste nell'aggiungere i pacchetti Firebase pertinenti al progetto Flutter. Il file firebase_options.dart
dovrebbe contenere errori, perché si basa su pacchetti Firebase che non sono stati ancora aggiunti. Nel terminale, assicurati di trovarti nella directory principale del progetto Flutter in flutter-codelabs/firebase-emulator-suite/start
. Poi, esegui i tre comandi che seguono:
flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add firebase_ui_auth
Questi sono gli unici pacchetti di cui hai bisogno in questo momento.
Inizializza Firebase
Per utilizzare i pacchetti aggiunti e DefaultFirebaseOptions.currentPlatform,
, aggiorna il codice nella funzione main
nel file main.dart
.
main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}
Questo codice fa due cose.
WidgetsFlutterBinding.ensureInitialized()
indica a Flutter di non iniziare a eseguire il codice del widget dell'applicazione finché il framework Flutter non è completamente avviato. Firebase utilizza i canali della piattaforma nativa, che richiedono l'esecuzione del framework.Firebase.initializeApp
configura una connessione tra la tua app Flutter e il tuo progetto Firebase.DefaultFirebaseOptions.currentPlatform
viene importato dal filefirebase_options.dart
generato. Questo valore statico rileva la piattaforma su cui stai eseguendo l'app e passa le chiavi Firebase corrispondenti.
4. Aggiungi la pagina iniziale di Firebase UI Auth
Firebase UI for Auth fornisce widget che rappresentano intere schermate dell'applicazione. Queste schermate gestiscono diversi flussi di autenticazione nell'applicazione, ad esempio Accesso, Registrazione, Password dimenticata, Profilo utente e altro ancora. Per iniziare, aggiungi una pagina di destinazione alla tua app che agisca come guardia di autenticazione per l'applicazione principale.
App Material o Cupertino
L'interfaccia utente di FlutterFire richiede che l'applicazione sia racchiusa in MaterialApp o CupertinoApp. A seconda della tua scelta, l'interfaccia utente rifletterà automaticamente le differenze dei widget Material o Cupertino. Per questo codelab, utilizza MaterialApp
, che è già stato aggiunto all'app in app.dart
.
app.dart
import 'package:flutter/material.dart';
import 'auth_gate.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const AuthGate(),
);
}
}
Controllare lo stato dell'autenticazione
Prima di poter mostrare una schermata di accesso, devi determinare se l'utente è attualmente autenticato. Il modo più comune per verificare questo problema è ascoltare authStateChanges di FirebaseAuth utilizzando il plug-in Firebase Auth.
Nell'esempio di codice riportato sopra, MaterialApp
sta creando un widget AuthGate
nel suo metodo di compilazione. Si tratta di un widget personalizzato, non fornito dall'interfaccia utente di FlutterFire.
Il widget deve essere aggiornato per includere lo stream authStateChanges
.
L'API authStateChanges
restituisce un Stream
con l'utente corrente (se ha eseguito l'accesso) o null se non l'ha fatto. Per iscriverti a questo stato nella nostra applicazione, puoi utilizzare il widget StreamBuilder di Flutter e passargli lo stream.
StreamBuilder
è un widget che si crea in base all'ultimo snapshot dei dati di uno stream che gli hai passato. Viene ricostruito automaticamente quando lo stream emette un nuovo snapshot.
Aggiorna il codice in auth_gate.dart
.
auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [],
);
}
return const HomeScreen();
},
);
}
}
- A
StreamBuilder.stream
viene passatoFirebaseAuth.instance.authStateChanged
, lo stream sopra menzionato, che restituirà un oggettoUser
di Firebase se l'utente ha eseguito l'autenticazione. In caso contrario, restituirànull
. - Successivamente, il codice utilizza
snapshot.hasData
per verificare se il valore dello stream contiene l'oggettoUser
. - In caso contrario, restituirà un widget
SignInScreen
. Al momento, questa schermata non fa nulla. Questo valore verrà aggiornato nel passaggio successivo. - In caso contrario, restituisce un
HomeScreen
, ovvero la parte principale dell'applicazione a cui solo gli utenti autenticati possono accedere.
SignInScreen
è un widget del pacchetto FlutterFire UI. Questo sarà l'obiettivo del passaggio successivo di questo codelab. A questo punto, quando esegui l'app, dovresti visualizzare una schermata di accesso vuota.
5. Schermata di accesso
Il widget SignInScreen
, fornito dall'interfaccia utente di FlutterFire, aggiunge le seguenti funzionalità:
- Consente agli utenti di accedere
- Se gli utenti hanno dimenticato la password, possono toccare "Password dimenticata?" e aprire un modulo per reimpostarla.
- Se un utente non ha ancora effettuato la registrazione, può toccare "Registrati" e verrà indirizzato a un altro modulo che gli consente di registrarsi.
Anche in questo caso, sono necessarie solo un paio di righe di codice. Ricorda il codice nel widget AuthGate:
auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(), // new
],
);
}
return const HomeScreen();
},
);
}
}
Il widget SignInScreen
e il relativo argomento providers
sono l'unico codice necessario per ottenere tutte le funzionalità sopra menzionate. Dovresti visualizzare una schermata di accesso con campi di testo "Email" e "Password", nonché un pulsante "Accedi".
Sebbene sia funzionale, manca di stile. Il widget espone i parametri per personalizzare l'aspetto della schermata di accesso. Ad esempio, potresti voler aggiungere il logo della tua azienda.
Personalizzare la schermata di accesso
headerBuilder
Utilizzando l'argomento SignInScreen.headerBuilder
, puoi aggiungere i widget che preferisci sopra il modulo di accesso. Questo widget viene visualizzato solo su schermi stretti, come i dispositivi mobili. Su schermi ampi, puoi utilizzare SignInScreen.sideBuilder
, di cui parleremo più avanti in questo codelab.
Aggiorna il file auth_gate.dart
con questo codice:
auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(),
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
L'argomento headerBuilder richiede una funzione di tipo HeaderBuilder, definita nel pacchetto FlutterFire UI.
typedef HeaderBuilder = Widget Function(
BuildContext context,
BoxConstraints constraints,
double shrinkOffset,
);
Poiché si tratta di un callback, espone i valori che potresti utilizzare, come BuildContext
e BoxConstraints
, e richiede di restituire un widget. Il widget restituito viene visualizzato nella parte superiore dello schermo. In questo esempio, il nuovo codice aggiunge un'immagine nella parte superiore dello schermo. La tua applicazione dovrebbe avere il seguente aspetto.
Subtitle Builder
La schermata di accesso espone tre parametri aggiuntivi che ti consentono di personalizzarla: subtitleBuilder
, footerBuilder
e sideBuilder
.
subtitleBuilder
è leggermente diverso in quanto gli argomenti del callback includono un'azione di tipo AuthAction
. AuthAction
è un enum che puoi utilizzare per rilevare se la schermata in cui si trova l'utente è quella di "accesso" o quella di "registrazione".
Aggiorna il codice in auth_gate.dart per utilizzare subtitleBuilder.
auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider()
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
);
}
return const HomeScreen();
},
);
}
}
Ricarica l'applicazione, che dovrebbe avere il seguente aspetto
Generatore di piè di pagina
L'argomento footerBuilder è lo stesso di subtitleBuilder. Non espone BoxConstraints
o shrinkOffset
, in quanto è destinato al testo anziché alle immagini. (anche se puoi aggiungere qualsiasi widget).
Aggiungi un piè di pagina alla schermata di accesso con questo codice.
auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider()
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) {
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
},
);
}
return const HomeScreen();
},
);
}}
Side Builder
L'argomento SignInScreen.sidebuilder accetta un callback e questa volta gli argomenti di questo callback sono BuildContext
e double shrinkOffset
. Il widget restituito da sideBuilder verrà visualizzato a sinistra del modulo di accesso e solo su schermi ampi. Ciò significa che il widget verrà visualizzato solo sulle app web e desktop.
Internamente, l'interfaccia utente di FlutterFire utilizza un punto di interruzione per determinare se devono essere visualizzati i contenuti dell'intestazione (su schermi alti, come i dispositivi mobili) o i contenuti laterali (su schermi ampi, computer o web). Nello specifico, se una schermata è larga più di 800 pixel, vengono visualizzati i contenuti del riquadro del generatore e non quelli dell'intestazione. Se lo schermo è largo meno di 800 pixel, vale il contrario.
Aggiorna il codice in auth_gate.dart per aggiungere i widget sideBuilder.
auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(),
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) {
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
},
sideBuilder: (context, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Ora la tua app dovrebbe avere questo aspetto quando espandi la larghezza della finestra (se utilizzi Flutter web o macOS).
Crea un utente
A questo punto, tutto il codice per questa schermata è stato completato. Tuttavia, prima di poter accedere, devi creare un utente. Puoi farlo con la schermata "Registrazione" oppure creare un utente nella Console Firebase.
Per utilizzare la console:
- Vai alla tabella "Utenti" nella Console Firebase.
- Fai clic qui
- Seleziona "flutterfire-ui-codelab" (o un altro progetto se hai utilizzato un nome diverso). Vedrai questa tabella:
- Fai clic sul pulsante "Aggiungi utente".
- Inserisci un indirizzo email e una password per il nuovo utente. Possono essere un'email e una password false, come ho inserito nell'immagine di seguito. Funziona, ma la funzionalità "Hai dimenticato la password" non funziona se utilizzi un indirizzo email falso.
- Fai clic su "Aggiungi utente"
Ora puoi tornare alla tua applicazione Flutter e far accedere un utente tramite la pagina di accesso. L'app dovrebbe avere il seguente aspetto:
6. Schermata del profilo
L'interfaccia utente di FlutterFire fornisce anche un widget ProfileScreen
, che offre molte funzionalità in poche righe di codice.
Aggiungere il widget ProfileScreen
Vai al file home.dart
nell'editor di testo. Aggiornalo con questo codice:
home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => const ProfileScreen(),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
Il nuovo codice della nota è il callback passato al pulsante IconButton.isPressed method.
. Quando viene premuto IconButton.isPressed method.
, l'applicazione crea un nuovo percorso anonimo e vi accede.IconButton
Questo percorso mostrerà il widget ProfileScreen
, restituito dal callback MaterialPageRoute.builder
.
Ricarica l'app e premi l'icona in alto a destra (nella barra dell'app). Viene visualizzata una pagina come questa:
Questa è l'interfaccia utente standard fornita dalla pagina dell'interfaccia utente di FlutterFire. Tutti i pulsanti e i campi di testo sono collegati a Firebase Auth e funzionano immediatamente. Ad esempio, puoi inserire un nome nel campo di testo "Nome" e l'interfaccia utente di FlutterFire chiamerà il metodo FirebaseAuth.instance.currentUser?.updateDisplayName
, che salverà il nome in Firebase.
Disconnessione
Al momento, se premi il pulsante "Uscire", l'app non cambia. Ti disconnetterà, ma non ti reindirizzerà al widget AuthGate. Per implementare questa funzionalità, utilizza il parametro ProfileScreen.actions.
Innanzitutto, aggiorna il codice in home.dart.
home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
})
],
),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
Ora, quando crei un'istanza di ProfileScreen
, passi anche un elenco di azioni all'argomento ProfileScreen.actions
. Queste azioni sono di tipo FlutterFireUiAction
. Esistono molti tipi di classi che sono sottotipi di FlutterFireUiAction
e, in genere, li utilizzi per indicare all'app di reagire a diverse modifiche dello stato di autenticazione. SignedOutAction chiama una funzione di callback che fornisci quando lo stato di autenticazione di Firebase cambia in modo che currentUser sia nullo.
Aggiungendo un callback che chiama Navigator.of(context).pop()
quando viene attivato SignedOutAction, l'app passa alla pagina precedente. In questa app di esempio esiste un solo percorso permanente, che mostra la pagina di accesso se non è presente un utente che ha eseguito l'accesso e la home page se è presente un utente. Poiché questo accade quando l'utente si disconnette, l'app mostrerà la pagina di accesso.
Personalizzare la pagina del profilo
Come la pagina di accesso, anche la pagina del profilo è personalizzabile. Innanzitutto, la nostra pagina attuale non consente di tornare alla home page una volta che un utente è nella pagina del profilo. Per risolvere il problema, aggiungi un'AppBar al widget ProfileScreen.
home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
appBar: AppBar(
title: const Text('User Profile'),
),
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
})
],
),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
L'argomento ProfileScreen.appBar
accetta un widget AppBar
dal pacchetto Flutter Material, quindi può essere trattato come qualsiasi altro AppBar
che hai creato e passato a un Scaffold
. In questo esempio, la funzionalità predefinita di aggiunta automatica di un pulsante "Indietro" viene mantenuta e la schermata ora ha un titolo.
Aggiungere bambini alla schermata del profilo
Il widget ProfileScreen ha anche un argomento facoltativo denominato children. Questo argomento accetta un elenco di widget, che verranno posizionati verticalmente all'interno di un widget Colonna già utilizzato internamente per creare la schermata Profilo. Questo widget Colonna nel metodo di compilazione ProfileScreen posiziona i figli che gli passi sopra il pulsante "Uscire".
Aggiorna il codice in home.dart per mostrare il logo dell'azienda qui, in modo simile alla schermata di accesso.
home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
appBar: AppBar(
title: const Text('User Profile'),
),
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
})
],
children: [
const Divider(),
Padding(
padding: const EdgeInsets.all(2),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
),
],
),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
Ricarica l'app e vedrai questo messaggio sullo schermo:
7. Accesso con autenticazione Google multipiattaforma
L'interfaccia utente di FlutterFire fornisce anche widget e funzionalità per l'autenticazione con provider di terze parti, come Google, Twitter, Facebook, Apple e GitHub.
Per l'integrazione con l'autenticazione Google, installa il plug-in ufficiale firebase_ui_oauth_google e le relative dipendenze, che gestiranno il flusso di autenticazione nativo. Nel terminale, vai alla directory principale del progetto Flutter e inserisci il seguente comando:
flutter pub add google_sign_in flutter pub add firebase_ui_oauth_google
Attivare il provider di accesso con Google
Poi, abilita il provider Google nella Console Firebase:
- Vai alla schermata Provider di accesso per l'autenticazione nella console.
- Fai clic su "Aggiungi nuovo fornitore".
- Seleziona "Google".
- Attiva/disattiva l'opzione "Attiva" e premi "Salva".
- Se viene visualizzata una finestra modale con informazioni sul download dei file di configurazione, fai clic su "Fine".
- Verifica che il provider di accesso con Google sia stato aggiunto.
Aggiungere il pulsante di accesso con Google
Con l'accesso con Google abilitato, aggiungi alla pagina di accesso il widget necessario per visualizzare un pulsante di accesso con Google stilizzato. Vai al file auth_gate.dart e aggiorna il codice come segue:
auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:firebase_ui_oauth_google/firebase_ui_oauth_google.dart'; // new
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(),
GoogleProvider(clientId: "YOUR_WEBCLIENT_ID"), // new
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) {
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
},
sideBuilder: (context, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
L'unico codice nuovo è l'aggiunta di GoogleProvider(clientId: "YOUR_WEBCLIENT_ID")
alla configurazione del widget SignInScreen.
Dopo aver aggiunto questo codice, ricarica l'app e vedrai un pulsante di accesso con Google.
Pulsante Configura l'accesso
Il pulsante non funziona senza una configurazione aggiuntiva. Se stai sviluppando con Flutter Web, questo è l'unico passaggio da aggiungere per farlo funzionare. Altre piattaforme richiedono passaggi aggiuntivi, che verranno discussi a breve.
- Vai alla pagina Fornitori di autenticazione nella console Firebase.
- Fai clic sul provider Google.
- Fai clic sul riquadro espandibile "Configurazione SDK web".
- Copia il valore da "ID client web"
- Torna all'editor di testo e aggiorna l'istanza di
GoogleProvider
nel fileauth_gate.dart
passando questo ID al parametro denominatoclientId
.
GoogleProvider(
clientId: "YOUR_WEBCLIENT_ID"
)
Dopo aver inserito l'ID client web, ricarica l'app. Quando premi il pulsante "Accedi con Google", viene visualizzata una nuova finestra (se utilizzi il web) che ti guida nella procedura di accesso con Google. Inizialmente avrà il seguente aspetto:
Configurare iOS
Affinché funzioni su iOS, è necessaria un'ulteriore procedura di configurazione.
- Vai alla schermata Impostazioni progetto nella Console Firebase. Vedrai una scheda che elenca le tue app Firebase, simile alla seguente:
- Fai clic su iOS. Tieni presente che il nome della tua applicazione sarà diverso dal mio. Se hai utilizzato il progetto
flutter-codelabs/firebase-auth-flutterfire-ui/start
per seguire questo codelab, al posto di "Completa" vedrai "Inizia". - Fai clic sul pulsante "GoogleServices-Info.plist" per scaricare il file di configurazione necessario.
- Trascina il file scaricato nella directory denominata
/ios/Runner
nel tuo progetto Flutter. - Apri Xcode eseguendo il seguente comando del terminale dalla radice del progetto:
open ios/Runner.xcworkspace
- Fai clic con il tasto destro del mouse sulla directory del programma di esecuzione e seleziona Aggiungi file a "Runner".
- Seleziona GoogleService-Info.plist dal gestore file.
- Torna nell'editor di testo (diverso da Xcode) e aggiungi gli attributi CFBundleURLTypes riportati di seguito nel file [my_project]/ios/Runner/Info.plist.
<!-- Put me in the [my_project]/ios/Runner/Info.plist file -->
<!-- Google Sign-in Section -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- TODO Replace this value: -->
<!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID -->
<string>com.googleusercontent.apps.861823949799-vc35cprkp249096uujjn0vvnmcvjppkn</string>
</array>
</dict>
</array>
<!-- End of the Google Sign-in Section -->
- Devi sostituire il valore
GoogleProvider.clientId
che hai aggiunto nella configurazione web con l'ID cliente associato al tuo ID cliente Firebase per iOS. Innanzitutto, puoi trovare questo ID nel filefirebase_options.dart
, all'interno della costanteiOS
. Copia il valore passato aiOSClientId
.
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'YOUR API KEY',
appId: 'YOUR APP ID',
messagingSenderId: '',
projectId: 'PROJECT_ID',
storageBucket: 'PROJECT_ID.firebasestorage.app',
iosClientId: 'IOS CLIENT ID', // Find your iOS client Id here.
iosBundleId: 'com.example.BUNDLE',
);
- Incolla questo valore nell'argomento
GoogleProvider.clientId
nel widgetAuthGate
.
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:firebase_ui_oauth_google/firebase_ui_oauth_google.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(),
GoogleProvider(clientId: "YOUR IOS CLIENT ID"), // replace String
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) {
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
},
sideBuilder: (context, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Se la tua app Flutter è già in esecuzione su iOS, devi chiuderla completamente e poi eseguire di nuovo l'applicazione. In caso contrario, esegui l'app su iOS.
8. Complimenti!
Hai completato il codelab sull'interfaccia utente di Firebase Auth per Flutter . Puoi trovare il codice completo di questo codelab nella directory "complete" su GitHub: Flutter Codelabs
Argomenti trattati
- Configurare un'app Flutter per l'utilizzo di Firebase
- Configurare un progetto Firebase nella Console Firebase
- Interfaccia a riga di comando FlutterFire
- interfaccia a riga di comando di Firebase
- Utilizzo di Firebase Authentication
- Utilizzare la UI di FlutterFire per gestire facilmente l'autenticazione Firebase nella tua app Flutter
Passaggi successivi
- Scopri di più sull'utilizzo di Firestore e Authentication in Flutter: Scopri Firebase per Flutter Codelab
- Scopri altri strumenti Firebase per la creazione della tua applicazione Flutter:
- Cloud Storage
- Cloud Functions
- Realtime Database
Scopri di più
- Sito Firebase: firebase.google.com
- Sito Flutter: flutter.dev
- Widget FlutterFire Firebase: firebase.flutter.dev
- Canale YouTube di Firebase
- Canale YouTube di Flutter
Sparky è qui per festeggiare con te.