Aggiungi un flusso di autenticazione utente a un'app Flutter utilizzando FirebaseUI

1. Prima di iniziare

In questo codelab imparerai come aggiungere l'autenticazione Firebase alla tua app Flutter utilizzando il pacchetto UI FlutterFire. Con questo pacchetto aggiungerai sia l'autenticazione email/password sia l'autenticazione di accesso con Google a un'app Flutter. Imparerai anche come configurare un progetto Firebase e utilizzare la CLI FlutterFire per inizializzare Firebase nella tua app Flutter.

Prerequisiti

Questo codelab presuppone che tu abbia una certa esperienza con Flutter. In caso contrario, potresti voler imparare prima le basi. Sono utili i seguenti link:

Dovresti anche avere una certa esperienza con Firebase, ma va bene se non hai mai aggiunto Firebase a un progetto Flutter. Se non hai familiarità con la console Firebase o se sei completamente nuovo a Firebase, consulta prima i seguenti collegamenti:

Cosa creerai

Questo codelab ti guida attraverso la creazione del flusso di autenticazione per un'app Flutter, utilizzando Firebase for Authentication. L'applicazione avrà una schermata di accesso, una schermata "Registrati", una schermata di ripristino della password e una schermata del profilo utente.

6604fc9157f2c6ae.pngeab9509a41074930.pngda49189a5838e0bb.pngb2ccfb3632b77878.png

Cosa imparerai

Questo codelab copre:

  • Aggiunta di Firebase a un'app Flutter
  • Configurazione della console Firebase
  • Utilizzo della CLI di Firebase per aggiungere Firebase alla tua applicazione
  • Utilizzo della CLI FlutterFire per generare la configurazione Firebase in Dart
  • Aggiunta dell'autenticazione Firebase alla tua app Flutter
  • Configurazione dell'autenticazione Firebase nella console
  • Aggiunta di email e password: accedi con il pacchetto firebase_ui_auth
  • Aggiunta della registrazione dell'utente con il pacchetto firebase_ui_auth
  • Aggiungere un messaggio "Password dimenticata?" pagina
  • Aggiunta dell'accesso a Google con firebase_ui_auth
  • Configurazione della tua app per funzionare con più provider di accesso.
  • Aggiunta di una schermata del profilo utente alla tua applicazione con il pacchetto firebase_ui_auth

Questo codelab riguarda specificamente l'aggiunta di un robusto sistema di autenticazione utilizzando il pacchetto firebase_ui_auth . Come vedrai, l'intera app, con tutte le funzionalità di cui sopra, può essere implementata con circa 100 righe di codice.

Di cosa avrai bisogno

  • Conoscenza operativa di Flutter e dell'SDK installato
  • Un editor di testo (JetBrains IDE, Android Studio e VS Code sono supportati da Flutter)
  • Browser Google Chrome o altro target di sviluppo preferito per Flutter. (Alcuni comandi del terminale in questo codelab presuppongono che tu stia eseguendo la tua app su Chrome)

2. Crea e configura un progetto Firebase

La prima attività che dovrai completare è la creazione di un progetto Firebase nella console web di Firebase.

Crea un progetto Firebase

  1. Accedi a Firebase .
  2. Nella console Firebase, fai clic su Aggiungi progetto (o Crea un progetto ) e inserisci un nome per il tuo progetto Firebase (ad esempio, " FlutterFire-UI-Codelab ").

df42a5e3d9584b48.png

  1. Fai clic sulle opzioni di creazione del progetto. Se richiesto, accetta i termini di Firebase. Salta la configurazione di Google Analytics perché non utilizzerai Analytics per questa app.

d1fcec48bf251eaa.png

Per ulteriori informazioni sui progetti Firebase, consulta Comprendere i progetti Firebase .

L'app che stai creando utilizza l'autenticazione Firebase per consentire ai tuoi utenti di accedere alla tua app. Consente inoltre ai nuovi utenti di registrarsi dall'applicazione Flutter.

L'autenticazione Firebase deve essere abilitata utilizzando la console Firebase e, una volta abilitata, richiede una configurazione speciale.

Abilita l'accesso e-mail per l'autenticazione Firebase

Per consentire agli utenti di accedere all'app Web, utilizzerai innanzitutto il metodo di accesso tramite posta elettronica/password . Successivamente aggiungerai il metodo di accesso con Google .

  1. Nella console Firebase, espandi il menu Crea nel pannello di sinistra.
  2. Fare clic su Autenticazione , quindi fare clic sul pulsante Inizia , quindi sulla scheda Metodo di accesso (oppure fare clic qui per passare direttamente alla scheda Metodo di accesso ).
  3. Fare clic su E-mail/Password nell'elenco Provider di accesso , impostare l'interruttore Abilita sulla posizione attiva, quindi fare clic su Salva . 58e3e3e23c2f16a4.png

3. Configura l'app Flutter

Prima di iniziare dovrai scaricare il codice iniziale e installare la CLI Firebase.

Ottieni il codice iniziale

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 dovrebbe essere clonato nella directory flutter-codelabs sul tuo computer, che contiene il codice per una raccolta di codelab. Il codice per 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 si chiama start . La directory start contiene un progetto incompleto ed è dove trascorrerai la maggior parte del tempo.

cd flutter-codelabs/firebase-auth-flutterfire-ui/start

Se vuoi andare avanti o vedere come dovrebbe apparire qualcosa una volta completato, cerca nella directory denominata complete per fare un riferimento incrociato.

Se desideri seguire il codelab e aggiungere tu stesso il codice, dovresti iniziare con l'app Flutter all'indirizzo flutter-codelabs/firebase-auth-flutterfire-ui/start e aggiungere il codice al progetto in tutto il codelab. Apri o importa quella directory nel tuo IDE preferito.

Installa l'interfaccia a riga di comando di Firebase

La CLI Firebase fornisce strumenti per la gestione dei tuoi progetti Firebase. La CLI è necessaria per la CLI FlutterFire, che installerai tra poco.

Esistono diversi modi per installare la CLI. Il modo più semplice, se utilizzi MacOS o Linux, è eseguire questo comando dal tuo terminale:

curl -sL https://firebase.tools | bash

Dopo aver installato la CLI, devi autenticarti con Firebase.

  1. Accedi a Firebase utilizzando il tuo account Google eseguendo il seguente comando:
firebase login
  1. Questo comando collega il tuo computer locale a Firebase e ti consente l'accesso ai tuoi progetti Firebase.
  1. Verifica che la CLI sia installata correttamente e abbia accesso al tuo account elencando i tuoi progetti Firebase. Esegui il seguente comando:
firebase projects:list
  1. L'elenco visualizzato dovrebbe essere lo stesso dei progetti Firebase elencati nella console Firebase . Dovresti vedere almeno flutterfire-ui-codelab.

Installa la CLI FlutterFire

La CLI FlutterFire è uno strumento che aiuta a facilitare il processo di installazione di Firebase su tutte le piattaforme supportate nella tua app Flutter. È basato sulla CLI di Firebase.

Innanzitutto, installa la CLI:

dart pub global activate flutterfire_cli

Assicurati che la CLI sia stata installata. Esegui il comando seguente e assicurati che la CLI visualizzi il menu della guida.

flutterfire -—help

Aggiungi il tuo progetto Firebase alla tua app Flutter

Configura FlutterFire

Puoi utilizzare FlutterFire per generare il codice Dart necessario per utilizzare Firebase nella tua app Flutter.

flutterfire configure

Quando esegui questo comando, ti verrà richiesto di selezionare quale progetto Firebase desideri utilizzare e quali piattaforme desideri configurare.

Le schermate seguenti mostrano le richieste a cui dovrai rispondere.

  1. Seleziona il progetto che desideri utilizzare. In questo caso, utilizzare flutterfire-ui-codelab 1359cdeb83204baa.png
  2. Seleziona quali piattaforme desideri utilizzare. In questo codelab sono riportati i passaggi per configurare l'autenticazione Firebase per Flutter per Web, iOS e Android, ma puoi configurare il tuo progetto Firebase per utilizzare tutte le opzioni. 301c9534f594f472.png
  3. Questa schermata mostra l'output alla fine del processo. Se hai familiarità con Firebase, noterai che non è stato necessario creare applicazioni della piattaforma (ad esempio un'applicazione Android) nella console e la CLI di FlutterFire lo ha fatto per te. 12199a85ade30459.png

Al termine, guarda l'app Flutter nel tuo editor di testo. La CLI FlutterFire ha generato un nuovo file chiamato firebase_options.dart . Questo file contiene una classe chiamata FirebaseOptions, che ha variabili statiche che contengono la configurazione Firebase necessaria per ciascuna 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.appspot.com',
   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.appspot.com',
 );

 static const FirebaseOptions ios = FirebaseOptions(
   apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
   appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
   messagingSenderId: '963656261848',
   projectId: 'flutterfire-ui-codelab',
   storageBucket: 'flutterfire-ui-codelab.appspot.com',
   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.appspot.com',
   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 chiamato 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'enumerazione TargetPlatform esposta da Flutter per rilevare la piattaforma su cui è in esecuzione la tua app, quindi restituisce i valori di configurazione Firebase necessari per l'applicazione Firebase corretta.

Aggiungi pacchetti Firebase all'app Flutter

Il passaggio finale della configurazione consiste nell'aggiungere i pacchetti Firebase pertinenti al tuo 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 essere nella root del progetto Flutter su 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 firebase_ui_auth

Questi sono gli unici pacchetti di cui hai bisogno a questo punto.

Inizializza Firebase

Per utilizzare i pacchetti aggiunti e DefaultFirebaseOptions.currentPlatform, aggiornare 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.

  1. WidgetsFlutterBinding.ensureInitialized() indica a Flutter di non avviare l'esecuzione del codice del widget dell'applicazione fino al completo avvio del framework Flutter. Firebase utilizza i canali della piattaforma nativa, che richiedono l'esecuzione del framework.
  2. Firebase.initializeApp configura una connessione tra la tua app Flutter e il tuo progetto Firebase. DefaultFirebaseOptions.currentPlatform viene importato dal nostro file firebase_options.dart generato. Questo valore statico rileva su quale piattaforma sei in esecuzione e trasmette le chiavi Firebase corrispondenti.

4. Aggiungi la pagina iniziale di autenticazione dell'interfaccia utente di Firebase

L'interfaccia utente di Firebase per Auth fornisce widget che rappresentano intere schermate nella tua applicazione. Queste schermate gestiscono diversi flussi di autenticazione nell'applicazione, ad esempio Accesso, Registrazione, Password dimenticata, Profilo utente e altro. Per iniziare, aggiungi una pagina di destinazione alla tua app che funge da protezione dell'autenticazione per l'applicazione principale.

Materiale o App 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 tra i widget Material o Cupertino. Per questo codelab, utilizza MaterialApp , già 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(),
   );
 }
}

Controlla lo stato di autenticazione

Prima di poter visualizzare una schermata di accesso, è necessario determinare se l'utente è attualmente autenticato. Il modo più comune per verificarlo è 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 build. (Questo è un widget personalizzato, non fornito dall'interfaccia utente FlutterFire.)

Il widget deve essere aggiornato per includere il flusso authStateChanges .

L'API authStateChanges restituisce un Stream con l'utente corrente (se ha effettuato l'accesso) o null se non lo è. Per iscriverti a questo stato nella nostra applicazione, puoi utilizzare il widget StreamBuilder di Flutter e passargli lo stream.

StreamBuilder è un widget che si costruisce da solo in base all'ultima istantanea di dati da uno stream che gli passi. Si ricostruisce automaticamente quando lo Stream emette una nuova istantanea.

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();
      },
    );
  }
}
  • StreamBuilder.stream viene passato a FirebaseAuth.instance.authStateChanged , il flusso sopra menzionato, che restituirà un oggetto User Firebase se l'utente si è autenticato. (Altrimenti restituirà null .)
  • Successivamente, il codice utilizza snapshot.hasData per verificare se il valore del flusso contiene l'oggetto User .
  • In caso contrario, restituirà un widget SignInScreen . Al momento, quella schermata non farà nulla. Questo verrà aggiornato nel passaggio successivo.
  • Altrimenti, restituisce un HomeScreen , che è la parte principale dell'applicazione a cui possono accedere solo gli utenti autenticati.

SignInScreen è un widget che proviene dal pacchetto FlutterFire UI. Questo sarà il focus del prossimo passo di questo codelab. Quando esegui l'app a questo punto, dovresti vedere una schermata di accesso vuota.

5. Schermata di accesso

Il widget SignInScreen , fornito dall'interfaccia utente FlutterFire, aggiunge le seguenti funzionalità:

  • Consente agli utenti di accedere
  • Se gli utenti hanno dimenticato la password, possono toccare "Password dimenticata?" ed essere indirizzato a un modulo per reimpostare la password
  • Se un utente non è ancora registrato, può toccare "Registrati" e verrà indirizzato a un altro modulo che gli consente di registrarsi.

Ancora una volta, ciò richiede solo un paio di righe di codice. Richiama 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 richiesto per ottenere tutte le funzionalità sopra menzionate. Ora dovresti vedere una schermata di accesso con input di testo "e-mail" e "password", oltre a un pulsante "Accedi".

Sebbene funzionale, manca di stile. Il widget espone parametri per personalizzare l'aspetto della schermata di accesso. Ad esempio, potresti voler aggiungere il logo della tua azienda.

Personalizza la schermata di accesso

headerBuilder

Utilizzando l'argomento SignInScreen.headerBuilder , puoi aggiungere qualsiasi widget desideri sopra il modulo di accesso. 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 del tipo HeaderBuilder, definita nel pacchetto UI FlutterFire.

typedef HeaderBuilder = Widget Function(
 BuildContext context,
 BoxConstraints constraints,
 double shrinkOffset,
);

Poiché si tratta di un callback, espone valori che potresti utilizzare, come BuildContext e BoxConstraints e richiede la restituzione di un widget. Qualunque widget restituisci viene visualizzato nella parte superiore dello schermo. In questo esempio, il nuovo codice aggiunge un'immagine nella parte superiore dello schermo. La tua applicazione ora dovrebbe assomigliare a questa.

73d7548d91bbd2ab.png

Generatore di sottotitoli

La schermata di accesso espone tre parametri aggiuntivi che consentono di personalizzare la schermata: subtitleBuilder , footerBuilder e sideBuilder .

Il subtitleBuilder è leggermente diverso in quanto gli argomenti di callback includono un'azione, che è di tipo AuthAction . AuthAction è un'enumerazione che puoi utilizzare per rilevare se la schermata su cui si trova l'utente è la schermata di "accesso" o la schermata 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 e dovrebbe assomigliare a questa

L'argomento footerBuilder è lo stesso di subtitleBuilder. Non espone BoxConstraints o shrinkOffset , poiché è destinato al testo anziché alle immagini. (Anche se puoi aggiungere qualsiasi widget desideri.)

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();
     },
   );
 }}

Costruttore laterale

L'argomento SignInScreen.sidebuilder accetta un callback e questa volta gli argomenti per quel callback sono BuildContext e double shrinkOffset . Il widget restituito da sideBuilder verrà visualizzato a sinistra del modulo di accesso e solo su schermi ampi. In pratica ciò significa che il widget verrà visualizzato solo su desktop e app Web.

Internamente, l'interfaccia utente di FlutterFire utilizza un punto di interruzione per determinare se il contenuto dell'intestazione deve essere mostrato (su schermi alti, come i dispositivi mobili) o il contenuto laterale (su schermi ampi, desktop o Web). Nello specifico, se uno schermo è largo più di 800 pixel, viene mostrato il contenuto del side builder e non il contenuto dell'intestazione. Se lo schermo è largo meno di 800 pixel, è vero il contrario.

Aggiorna il codice in auth_gate.dart per aggiungere 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();
     },
   );
 }
}

La tua app ora dovrebbe apparire così quando espandi la larghezza della finestra (se utilizzi Flutter web o MacOS).

8dc60b4e5d7dd2d0.png

Crea un utente

A questo punto, tutto il codice per questa schermata è terminato. Prima di poter accedere, tuttavia, è necessario creare un utente. Puoi farlo con la schermata "Registrati" oppure puoi creare un utente nella console Firebase.

Per utilizzare la console:

  1. Vai alla tabella "Utenti" nella console Firebase.
  2. clicca qui
  3. Seleziona "flutterfire-ui-codelab" (o un altro progetto se hai utilizzato un nome diverso). Vedrai questa tabella:

f038fd9a58ed60d9.png

  1. Fare clic sul pulsante "Aggiungi utente".

2d78390d4c5dbbfa.png

  1. Inserisci un indirizzo email e una password per il nuovo utente. Potrebbero trattarsi di un'e-mail e una password false, come ho inserito nell'immagine qui sotto. Funzionerà, ma la funzionalità "Password dimenticata" non funzionerà se utilizzi un indirizzo email falso.

62ba0feb33d54add.png

  1. Fai clic su "Aggiungi utente"

32b236b3ef94d4c7.png

Ora puoi tornare alla tua applicazione Flutter e accedere come utente tramite la pagina di accesso. La tua app dovrebbe assomigliare a questa:

dd43d260537f3b1a.png

6. Schermata del profilo

L'interfaccia utente di FlutterFire fornisce anche un widget ProfileScreen che, ancora una volta, offre molte funzionalità in poche righe di codice.

Aggiungi il widget ProfileScreen

Passare 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 degno di nota è il callback passato al IconButton.isPressed method. Quando viene premuto IconButton , l'applicazione crea un nuovo percorso anonimo e vi accede. Tale percorso visualizzerà il widget ProfileScreen , che viene restituito dal callback MaterialPageRoute.builder .

Ricarica la tua app e premi l'icona in alto a destra (nella barra delle app) e verrà visualizzata una pagina come questa:

36487fc4ab4f26a7.png

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à quel nome in Firebase.

Uscita

In questo momento, se premi il pulsante "Esci", l'app non cambierà. Verrai disconnesso, ma non verrai reindirizzato al widget AuthGate. Per implementare ciò, utilizzare 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 , le passi anche un elenco di azioni all'argomento ProfileScreen.actions . Queste azioni sono del tipo FlutterFireUiAction . Esistono molte classi diverse che sono sottotipi di FlutterFireUiAction e in generale le usi per indicare alla tua app di reagire a diversi cambiamenti dello stato di autenticazione. SignedOutAction chiama una funzione di callback assegnata quando lo stato di autenticazione di Firebase cambia in currentUser che diventa null.

Aggiungendo un callback che chiama Navigator.of(context).pop() quando si attiva SignedOutAction, l'app passerà alla pagina precedente. In questa app di esempio è presente un solo percorso permanente, che mostra la pagina di accesso se non è presente un utente che ha effettuato l'accesso e la home page se è presente un utente. Poiché ciò accade quando l'utente si disconnette, l'app visualizzerà la pagina di accesso.

Personalizza la pagina del profilo

Similmente alla pagina di accesso, la pagina del profilo è personalizzabile. Innanzitutto, la nostra pagina corrente non ha modo di tornare alla home page una volta che un utente si trova nella pagina del profilo. Risolvi questo problema fornendo al widget ProfileScreen un'AppBar.

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 altra AppBar che hai creato e passato a uno Scaffold . In questo esempio, viene mantenuta la funzionalità predefinita di aggiunta automatica di un pulsante "Indietro" e la schermata ora ha un titolo.

Aggiungi bambini alla schermata del profilo

Il widget ProfileScreen ha anche un argomento facoltativo denominato children. Questo argomento accetta un elenco di widget e tali widget verranno posizionati verticalmente all'interno di un widget Colonna già utilizzato internamente per creare ProfileScreen. Questo widget Colonna nel metodo di compilazione ProfileScreen posizionerà i figli che gli passi sopra il pulsante "Esci".

Aggiorna il codice in home.dart per mostrare qui il logo dell'azienda, 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 la tua app e vedrai questo sullo schermo:

ebe5792b765dbf87.png

7. Accesso multipiattaforma con autenticazione Google

L'interfaccia utente di FlutterFire fornisce anche widget e funzionalità per l'autenticazione con fornitori di terze parti, come Google, Twitter, Facebook, Apple e Github.

Per integrarsi con l'autenticazione di Google, installa il plug-in firebase_ui_oauth_google ufficiale e le sue dipendenze, che gestiranno il flusso di autenticazione nativa. Nel terminale, vai alla radice del tuo progetto flutter e inserisci il seguente comando:

flutter pub add google_sign_in
flutter pub add firebase_ui_oauth_google

Abilita il provider di accesso Google

Successivamente, abilita il provider Google nella console Firebase :

  1. Passare alla schermata Provider di accesso di autenticazione nella console.
  2. Fare clic su "Aggiungi nuovo fornitore". 8286fb28be94bf30.png
  3. Seleziona "Google". c4e28e6f4974be7f.png
  4. Attiva l'interruttore denominato "Abilita" e premi "Salva". e74ff86990763826.png
  5. Se viene visualizzata una finestra modale con informazioni sul download dei file di configurazione, fare clic su "Fine".
  6. Conferma che il provider di accesso di Google sia stato aggiunto. 5329ce0543c90d95.png

Aggiungi il pulsante di accesso di Google

Con l'accesso a Google abilitato, aggiungi il widget necessario per visualizzare un pulsante di accesso di Google stilizzato nella pagina di accesso. Passare al file auth_gate.dart e aggiornare 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 nuovo codice qui è l'aggiunta di GoogleProvider(clientId: "YOUR_WEBCLIENT_ID") alla configurazione del widget SignInScreen.

Detto questo, ricarica la tua app e vedrai un pulsante di accesso a Google.

aca71a46a011bfb5.png

Configura il pulsante di accesso

Il pulsante non funziona senza una configurazione aggiuntiva. Se stai sviluppando con Flutter Web, questo è l'unico passaggio che devi aggiungere affinché funzioni. Altre piattaforme richiedono passaggi aggiuntivi, che verranno discussi tra breve.

  1. Passa alla pagina Provider di autenticazione nella console Firebase .
  2. Fare clic sul fornitore di Google. 9b3a325c5eca6e49.png
  3. Fare clic sul pannello di espansione "Configurazione Web SDK".
  4. Copia il valore da "ID client Web" 711a79f0d931c60f.png
  5. Torna al tuo editor di testo e aggiorna l'istanza di GoogleProvider nel file auth_gate.dart passando questo ID al parametro denominato clientId .
GoogleProvider(
   clientId: "YOUR_WEBCLIENT_ID"
)

Una volta inserito l'ID del client Web, ricarica l'app. Quando premi il pulsante "Accedi con Google", verrà visualizzata una nuova finestra (se utilizzi il Web) che ti guiderà attraverso il flusso di accesso di Google. Inizialmente, appare così:

14e73e3c9de704bb.png

Configura iOS

Affinché funzioni su iOS, è necessario un processo di configurazione aggiuntivo.

  1. Passa alla schermata Impostazioni progetto nella console Firebase . Ci sarà una scheda che elenca le tue app Firebase simile a questa: fefa674acbf213cc.png
  2. Fare clic su iOS. Tieni presente che il nome della tua applicazione sarà diverso dal mio. Dove il mio dice "completo", il tuo dirà "inizia", ​​se hai utilizzato il progetto flutter-codelabs/firebase-auth-flutterfire-ui/start per seguire questo codelab.
  3. Fai clic sul pulsante "GoogleServices-Info.plist" per scaricare il file di configurazione necessario. f89b3192871dfbe3.png
  4. Trascina e rilascia il file scaricato nella directory denominata . /ios/Runner nel tuo progetto Flutter.
  5. Apri Xcode eseguendo il seguente comando terminale dalla radice del tuo progetto:

aprire ios/Runner.xcworkspace

  1. Fare clic con il tasto destro sulla directory del Runner e selezionare Aggiungi file a "Runner". 858986063a4c5201.png
  2. Seleziona GoogleService-Info.plist dal file manager.
  3. Tornando al tuo editor di testo (che non è Xcode), aggiungi gli attributi CFBundleURLTypes 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 -->

Se la tua app Flutter è già in esecuzione su iOS, devi spegnerla completamente e quindi eseguire nuovamente l'applicazione. Altrimenti, esegui l'app in iOS.

8. Congratulazioni!

Hai completato l'interfaccia utente di autenticazione Firebase per il codelab Flutter. Puoi trovare il codice completo per questo Codelab nella directory "complete" su github: Flutter Codelabs

Di cosa abbiamo parlato

  • Configurazione di un'app Flutter per utilizzare Firebase
  • Configurazione di un progetto Firebase nella console Firebase
  • CLI di FlutterFire
  • CLI Firebase
  • Utilizzo dell'autenticazione Firebase
  • Utilizzo dell'interfaccia utente FlutterFire per gestire facilmente l'autenticazione Firebase nella tua app Flutter

Prossimi passi

Saperne di più

Sparky è qui per festeggiare con te!

2a0ad195769368b1.gif