Ajouter un flux d'authentification utilisateur à une application Flutter à l'aide de FirebaseUI

1. Avant de commencer

Dans cet atelier de programmation, vous apprendrez comment ajouter l'authentification Firebase à votre application Flutter à l'aide du package d'interface utilisateur FlutterFire. Avec ce package, vous ajouterez à la fois l'authentification par e-mail/mot de passe et l'authentification de connexion Google à une application Flutter. Vous apprendrez également à configurer un projet Firebase et à utiliser la CLI FlutterFire pour initialiser Firebase dans votre application Flutter.

Conditions préalables

Cet atelier de programmation suppose que vous possédez une certaine expérience de Flutter. Sinon, vous voudrez peut-être d’abord apprendre les bases. Les liens suivants sont utiles :

Vous devez également avoir une certaine expérience de Firebase, mais ce n'est pas grave si vous n'avez jamais ajouté Firebase à un projet Flutter. Si vous n'êtes pas familier avec la console Firebase, ou si vous êtes complètement nouveau sur Firebase, consultez d'abord les liens suivants :

Ce que vous allez créer

Cet atelier de programmation vous guide dans la création du flux d'authentification pour une application Flutter, à l'aide de Firebase for Authentication. L'application aura un écran de connexion, un écran « S'inscrire », un écran de récupération de mot de passe et un écran de profil utilisateur.

6604fc9157f2c6ae.pngeab9509a41074930.pngda49189a5838e0bb.pngb2ccfb3632b77878.png

Ce que vous apprendrez

Cet atelier de programmation couvre :

  • Ajouter Firebase à une application Flutter
  • Configuration de la console Firebase
  • Utiliser Firebase CLI pour ajouter Firebase à votre application
  • Utilisation de FlutterFire CLI pour générer la configuration Firebase dans Dart
  • Ajout de l'authentification Firebase à votre application Flutter
  • Configuration de l'authentification Firebase dans la console
  • Ajout d'une connexion par e-mail et par mot de passe avec le package firebase_ui_auth
  • Ajout de l'enregistrement des utilisateurs avec le package firebase_ui_auth
  • Ajout d'un message « Mot de passe oublié ? » page
  • Ajout de Google Sign-in avec firebase_ui_auth
  • Configuration de votre application pour qu'elle fonctionne avec plusieurs fournisseurs de connexion.
  • Ajout d'un écran de profil utilisateur à votre application avec le package firebase_ui_auth

Cet atelier de programmation concerne spécifiquement l'ajout d'un système d'authentification robuste à l'aide du package firebase_ui_auth . Comme vous le verrez, l'ensemble de cette application, avec toutes les fonctionnalités ci-dessus, peut être implémentée avec environ 100 lignes de code.

Ce dont vous aurez besoin

  • Connaissance pratique de Flutter et du SDK installé
  • Un éditeur de texte (les IDE JetBrains, Android Studio et VS Code sont pris en charge par Flutter)
  • Navigateur Google Chrome ou votre autre cible de développement préférée pour Flutter. (Certaines commandes de terminal dans cet atelier de programmation supposeront que vous exécutez votre application sur Chrome)

2. Créez et configurez un projet Firebase

La première tâche que vous devrez effectuer consiste à créer un projet Firebase dans la console Web de Firebase.

Créer un projet Firebase

  1. Connectez-vous à Firebase .
  2. Dans la console Firebase, cliquez sur Ajouter un projet (ou Créer un projet ) et saisissez un nom pour votre projet Firebase (par exemple, " FlutterFire-UI-Codelab ").

df42a5e3d9584b48.png

  1. Cliquez sur les options de création de projet. Acceptez les conditions de Firebase si vous y êtes invité. Ignorez la configuration de Google Analytics, car vous n'utiliserez pas Analytics pour cette application.

d1fcec48bf251eaa.png

Pour en savoir plus sur les projets Firebase, consultez Comprendre les projets Firebase .

L'application que vous créez utilise l'authentification Firebase pour permettre à vos utilisateurs de se connecter à votre application. Il permet également aux nouveaux utilisateurs de s'inscrire depuis l'application Flutter.

L'authentification Firebase doit être activée à l'aide de la console Firebase et nécessite une configuration spéciale une fois activée.

Activer la connexion par e-mail pour l'authentification Firebase

Pour permettre aux utilisateurs de se connecter à l'application Web, vous utiliserez d'abord la méthode de connexion par e-mail/mot de passe . Plus tard, vous ajouterez la méthode Google Sign-In .

  1. Dans la console Firebase, développez le menu Créer dans le panneau de gauche.
  2. Cliquez sur Authentification , puis cliquez sur le bouton Commencer , puis sur l'onglet Méthode de connexion (ou cliquez ici pour accéder directement à l'onglet Méthode de connexion ).
  3. Cliquez sur E-mail/Mot de passe dans la liste Fournisseurs de connexion , placez le commutateur Activer sur la position activé, puis cliquez sur Enregistrer . 58e3e3e23c2f16a4.png

3. Configurer l'application Flutter

Vous devrez télécharger le code de démarrage et installer la CLI Firebase avant de commencer.

Obtenez le code de démarrage

Clonez le dépôt GitHub à partir de la ligne de commande :

git clone https://github.com/flutter/codelabs.git flutter-codelabs

Alternativement, si l'outil CLI de GitHub est installé :

gh repo clone flutter/codelabs flutter-codelabs

L'exemple de code doit être cloné dans le répertoire flutter-codelabs de votre ordinateur, qui contient le code d'une collection d'ateliers de programmation. Le code de cet atelier de programmation se trouve dans le sous-répertoire flutter-codelabs/firebase-auth-flutterfire-ui .

Le répertoire flutter-codelabs/firebase-auth-flutterfire-ui contient deux projets Flutter. L’un est appelé complete et l’autre est appelé start . Le répertoire start contient un projet incomplet et c'est là que vous passerez le plus de temps.

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

Si vous souhaitez avancer ou voir à quoi devrait ressembler quelque chose une fois terminé, recherchez dans le répertoire nommé complete pour effectuer une référence croisée.

Si vous souhaitez suivre l'atelier de programmation et ajouter du code vous-même, vous devez commencer par l'application Flutter à l'adresse flutter-codelabs/firebase-auth-flutterfire-ui/start , et ajouter du code à ce projet tout au long de l'atelier de programmation. Ouvrez ou importez ce répertoire dans votre IDE préféré.

Installer la CLI Firebase

La CLI Firebase fournit des outils pour gérer vos projets Firebase. La CLI est requise pour la CLI FlutterFire, que vous installerez dans un instant.

Il existe différentes manières d'installer la CLI. Le moyen le plus simple, si vous utilisez MacOS ou Linux, est d'exécuter cette commande depuis votre terminal :

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

Après avoir installé la CLI, vous devez vous authentifier auprès de Firebase.

  1. Connectez-vous à Firebase à l'aide de votre compte Google en exécutant la commande suivante :
firebase login
  1. Cette commande connecte votre ordinateur local à Firebase et vous donne accès à vos projets Firebase.
  1. Testez que la CLI est correctement installée et a accès à votre compte en répertoriant vos projets Firebase. Exécutez la commande suivante :
firebase projects:list
  1. La liste affichée doit être la même que celle des projets Firebase répertoriés dans la console Firebase . Vous devriez voir au moins flutterfire-ui-codelab.

Installez la CLI FlutterFire

La CLI FlutterFire est un outil qui facilite le processus d'installation de Firebase sur toutes les plates-formes prises en charge dans votre application Flutter. Il est construit sur la CLI Firebase.

Tout d'abord, installez la CLI :

dart pub global activate flutterfire_cli

Assurez-vous que la CLI a été installée. Exécutez la commande suivante et assurez-vous que la CLI affiche le menu d'aide.

flutterfire -—help

Ajoutez votre projet Firebase à votre application Flutter

Configurer FlutterFire

Vous pouvez utiliser FlutterFire pour générer le code Dart nécessaire pour utiliser Firebase dans votre application Flutter.

flutterfire configure

Lorsque cette commande est exécutée, vous serez invité à sélectionner le projet Firebase que vous souhaitez utiliser et les plates-formes que vous souhaitez configurer.

Les captures d'écran suivantes montrent les invites auxquelles vous devrez répondre.

  1. Sélectionnez le projet que vous souhaitez utiliser. Dans ce cas, utilisez flutterfire-ui-codelab 1359cdeb83204baa.png
  2. Sélectionnez les plateformes que vous souhaitez utiliser. Dans cet atelier de programmation, vous trouverez des étapes pour configurer l'authentification Firebase pour Flutter pour le Web, iOS et Android, mais vous pouvez configurer votre projet Firebase pour utiliser toutes les options. 301c9534f594f472.png
  3. Cette capture d'écran montre le résultat à la fin du processus. Si vous connaissez Firebase, vous remarquerez que vous n'avez pas besoin de créer d'applications de plate-forme (par exemple, une application Android) dans la console et que la CLI FlutterFire l'a fait pour vous. 12199a85ade30459.png

Une fois cette opération terminée, regardez l'application Flutter dans votre éditeur de texte. FlutterFire CLI a généré un nouveau fichier appelé firebase_options.dart . Ce fichier contient une classe appelée FirebaseOptions, qui possède des variables statiques contenant la configuration Firebase nécessaire pour chaque plate-forme. Si vous avez sélectionné toutes les plates-formes lorsque vous avez exécuté flutterfire configure , vous verrez des valeurs statiques nommées web , android , ios et 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 utilise le mot application pour faire référence à une version spécifique d'une plate-forme spécifique dans un projet Firebase. Par exemple, le projet Firebase appelé FlutterFire-ui-codelab possède plusieurs applications : une pour Android, une pour iOS, une pour MacOS et une pour le Web.

La méthode DefaultFirebaseOptions.currentPlatform utilise l'énumération TargetPlatform exposée par Flutter pour détecter la plate-forme sur laquelle votre application s'exécute, puis renvoie les valeurs de configuration Firebase nécessaires à l'application Firebase correcte.

Ajouter des packages Firebase à l'application Flutter

La dernière étape de configuration consiste à ajouter les packages Firebase pertinents à votre projet Flutter. Le fichier firebase_options.dart devrait contenir des erreurs, car il repose sur des packages Firebase qui n'ont pas encore été ajoutés. Dans le terminal, assurez-vous que vous êtes à la racine du projet Flutter à flutter-codelabs/firebase-emulator-suite/start . Ensuite, exécutez les trois commandes suivantes :

flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add firebase_ui_auth

Ce sont les seuls packages dont vous avez besoin à ce stade.

Initialiser Firebase

Afin d'utiliser les packages ajoutés et DefaultFirebaseOptions.currentPlatform, mettez à jour le code dans la fonction main dans le fichier main.dart .

main.dart

void main() async {
 WidgetsFlutterBinding.ensureInitialized();
 await Firebase.initializeApp(
   options: DefaultFirebaseOptions.currentPlatform,
 );


 runApp(const MyApp());
}

Ce code fait deux choses.

  1. WidgetsFlutterBinding.ensureInitialized() indique à Flutter de ne pas commencer à exécuter le code du widget d'application tant que le framework Flutter n'est pas complètement démarré. Firebase utilise des canaux de plate-forme natifs, qui nécessitent l'exécution du framework.
  2. Firebase.initializeApp établit une connexion entre votre application Flutter et votre projet Firebase. Le DefaultFirebaseOptions.currentPlatform est importé à partir de notre fichier firebase_options.dart généré. Cette valeur statique détecte la plate-forme sur laquelle vous exécutez et transmet les clés Firebase correspondantes.

4. Ajouter la page d'authentification initiale de l'interface utilisateur Firebase

Firebase UI for Auth fournit des widgets qui représentent des écrans entiers de votre application. Ces écrans gèrent différents flux d'authentification dans votre application, tels que la connexion, l'inscription, le mot de passe oublié, le profil utilisateur, etc. Pour commencer, ajoutez une page de destination à votre application qui agit comme un garde d'authentification pour l'application principale.

Matériel ou application Cupertino

L'interface utilisateur de FlutterFire nécessite que votre application soit enveloppée dans une MaterialApp ou une CupertinoApp. Selon votre choix, l'interface utilisateur reflétera automatiquement les différences entre les widgets Material ou Cupertino. Pour cet atelier de programmation, utilisez MaterialApp , qui est déjà ajouté à l'application dans app.dart .

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

Vérifier l'état de l'authentification

Avant de pouvoir afficher un écran de connexion, vous devez déterminer si l'utilisateur est actuellement authentifié. Le moyen le plus courant de vérifier cela consiste à écouter les authStateChanges de FirebaseAuth à l'aide du plugin Firebase Auth .

Dans l'exemple de code ci-dessus, MaterialApp crée un widget AuthGate dans sa méthode de construction. (Il s'agit d'un widget personnalisé, non fourni par l'interface utilisateur FlutterFire.)

Ce widget doit être mis à jour pour inclure le flux authStateChanges .

L'API authStateChanges renvoie un Stream avec soit l'utilisateur actuel (s'il est connecté), soit null s'il ne l'est pas. Pour vous abonner à cet état dans notre application, vous pouvez utiliser le widget StreamBuilder de Flutter et lui transmettre le flux.

StreamBuilder est un widget qui se construit lui-même sur la base du dernier instantané des données d'un Stream que vous lui transmettez. Il se reconstruit automatiquement lorsque le Stream émet un nouvel instantané.

Mettez à jour le code dans 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 est transmis à FirebaseAuth.instance.authStateChanged , le flux susmentionné, qui renverra un objet Firebase User si l'utilisateur s'est authentifié. (Sinon, il renverra null .)
  • Ensuite, le code utilise snapshot.hasData pour vérifier si la valeur du flux contient l'objet User .
  • Si ce n'est pas le cas, il renverra un widget SignInScreen . Actuellement, cet écran ne fera rien. Celui-ci sera mis à jour à l'étape suivante.
  • Sinon, il renvoie un HomeScreen , qui est la partie principale de l'application à laquelle seuls les utilisateurs authentifiés peuvent accéder.

Le SignInScreen est un widget issu du package FlutterFire UI. Ce sera l'objet de la prochaine étape de cet atelier de programmation. Lorsque vous exécutez l'application à ce stade, vous devriez voir un écran de connexion vide.

5. Écran de connexion

Le widget SignInScreen , fourni par FlutterFire UI, ajoute les fonctionnalités suivantes :

  • Permet aux utilisateurs de se connecter
  • Si les utilisateurs ont oublié leur mot de passe, ils peuvent appuyer sur « Mot de passe oublié ? » et être redirigé vers un formulaire pour réinitialiser son mot de passe
  • Si un utilisateur n'est pas encore enregistré, il peut appuyer sur « S'inscrire » et être redirigé vers un autre formulaire qui lui permet de s'inscrire.

Encore une fois, cela ne nécessite que quelques lignes de code. Rappelez le code dans le 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();
      },
    );
  }
}

Le widget SignInScreen et son argument providers sont le seul code requis pour obtenir toutes les fonctionnalités susmentionnées. Vous devriez maintenant voir un écran de connexion contenant des saisies de texte « e-mail » et « mot de passe », ainsi qu'un bouton « Se connecter ».

Bien que fonctionnel, il manque de style. Le widget expose des paramètres pour personnaliser l'apparence de l'écran de connexion. Par exemple, vous souhaiterez peut-être ajouter le logo de votre entreprise.

Personnaliser l'écran de connexion

en-têteBuilder

À l’aide de l’argument SignInScreen.headerBuilder , vous pouvez ajouter les widgets de votre choix au-dessus du formulaire de connexion. Mettez à jour le fichier auth_gate.dart avec ce code :

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'argument headerBuilder nécessite une fonction du type HeaderBuilder, qui est définie dans le package FlutterFire UI.

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

Puisqu'il s'agit d'un rappel, il expose les valeurs que vous pouvez utiliser, telles que BuildContext et BoxConstraints , et nécessite que vous renvoyiez un widget. Quel que soit le widget que vous renvoyez, il est affiché en haut de l'écran. Dans cet exemple, le nouveau code ajoute une image en haut de l'écran. Votre application devrait maintenant ressembler à ceci.

73d7548d91bbd2ab.png

Générateur de sous-titres

L'écran de connexion expose trois paramètres supplémentaires qui vous permettent de personnaliser l'écran : subtitleBuilder , footerBuilder et sideBuilder .

Le subtitleBuilder est légèrement différent dans la mesure où les arguments de rappel incluent une action de type AuthAction . AuthAction est une énumération que vous pouvez utiliser pour détecter si l'écran sur lequel se trouve l'utilisateur est l'écran « connexion » ou l'écran « s'inscrire ».

Mettez à jour le code dans auth_gate.dart pour utiliser 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();
     },
   );
 }
}

Rechargez l'application, et elle devrait ressembler à ceci

L'argument footerBuilder est le même que celui de subtitleBuilder. Il n'expose pas BoxConstraints ou shrinkOffset , car il est destiné au texte plutôt qu'aux images. (Bien que vous puissiez ajouter n'importe quel widget de votre choix.)

Ajoutez un pied de page à votre écran de connexion avec ce code.

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

Constructeur latéral

L'argument SignInScreen.sidebuilder accepte un rappel, et cette fois les arguments de ce rappel sont BuildContext et double shrinkOffset . Le widget renvoyé par sideBuilder sera affiché à gauche du formulaire de connexion, et uniquement sur des écrans larges. En fait, cela signifie que le widget ne sera affiché que sur les applications de bureau et Web.

En interne, l'interface utilisateur de FlutterFire utilise un point d'arrêt pour déterminer si le contenu de l'en-tête doit être affiché (sur des écrans grands, comme les mobiles) ou si le contenu latéral doit être affiché (sur des écrans larges, sur un ordinateur de bureau ou sur le Web). Plus précisément, si un écran fait plus de 800 pixels de large, le contenu du générateur latéral est affiché, mais pas le contenu de l'en-tête. Si l’écran fait moins de 800 pixels de large, c’est l’inverse.

Mettez à jour le code dans auth_gate.dart pour ajouter des widgets 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();
     },
   );
 }
}

Votre application devrait maintenant ressembler à ceci lorsque vous agrandissez la largeur de la fenêtre (si vous utilisez Flutter Web ou MacOS).

8dc60b4e5d7dd2d0.png

Créer un utilisateur

À ce stade, tout le code de cet écran est terminé. Cependant, avant de pouvoir vous connecter, vous devez créer un utilisateur. Vous pouvez le faire avec l'écran "S'inscrire" ou créer un utilisateur dans la console Firebase.

Pour utiliser la console :

  1. Accédez au tableau "Utilisateurs" dans la console Firebase.
  2. Cliquez ici
  3. Sélectionnez « flutterfire-ui-codelab » (ou un autre projet si vous avez utilisé un nom différent). Vous verrez ce tableau :

f038fd9a58ed60d9.png

  1. Cliquez sur le bouton "Ajouter un utilisateur".

2d78390d4c5dbbfa.png

  1. Entrez une adresse e-mail et un mot de passe pour le nouvel utilisateur. Il peut s'agir d'un faux e-mail et d'un faux mot de passe, comme je l'ai entré dans l'image ci-dessous. Cela fonctionnera, mais la fonctionnalité « Mot de passe oublié » ne fonctionnera pas si vous utilisez une fausse adresse e-mail.

62ba0feb33d54add.png

  1. Cliquez sur "Ajouter un utilisateur"

32b236b3ef94d4c7.png

Vous pouvez désormais revenir à votre application Flutter et connecter un utilisateur via la page de connexion. Votre application devrait ressembler à ceci :

dd43d260537f3b1a.png

6. Écran de profil

L'interface utilisateur de FlutterFire fournit également un widget ProfileScreen , qui, encore une fois, vous offre de nombreuses fonctionnalités en quelques lignes de code.

Ajouter un widget ProfileScreen

Accédez au fichier home.dart dans votre éditeur de texte. Mettez-le à jour avec ce code :

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

Le nouveau code à noter est le rappel transmis à la IconButton.isPressed method. Lorsque vous appuyez sur cet IconButton , votre application crée un nouvel itinéraire anonyme et y accède. Cet itinéraire affichera le widget ProfileScreen , qui est renvoyé par le rappel MaterialPageRoute.builder .

Rechargez votre application et appuyez sur l'icône en haut à droite (dans la barre d'application), et elle affichera une page comme celle-ci :

36487fc4ab4f26a7.png

Il s'agit de l'interface utilisateur standard fournie par la page de l'interface utilisateur de FlutterFire. Tous les boutons et champs de texte sont connectés à Firebase Auth et fonctionnent immédiatement. Par exemple, vous pouvez saisir un nom dans le champ de texte « Nom » et FlutterFire UI appellera la méthode FirebaseAuth.instance.currentUser?.updateDisplayName , qui enregistrera ce nom dans Firebase.

Déconnecter

Pour le moment, si vous appuyez sur le bouton « Déconnexion », l'application ne changera pas. Cela vous déconnectera, mais vous ne serez pas redirigé vers le widget AuthGate. Pour implémenter cela, utilisez le paramètre ProfileScreen.actions.

Tout d’abord, mettez à jour le code dans home.dart.

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

Désormais, lorsque vous créez une instance de ProfileScreen , vous lui transmettez également une liste d'actions à l'argument ProfileScreen.actions . Ces actions sont du type FlutterFireUiAction . Il existe de nombreuses classes différentes qui sont des sous-types de FlutterFireUiAction et, en général, vous les utilisez pour indiquer à votre application de réagir aux différents changements d'état d'authentification. Le SignedOutAction appelle une fonction de rappel que vous lui donnez lorsque l'état d'authentification de Firebase passe à currentUser étant nul.

En ajoutant un rappel qui appelle Navigator.of(context).pop() lorsque SignedOutAction se déclenche, l'application accédera à la page précédente. Dans cet exemple d'application, il n'y a qu'un seul itinéraire permanent, qui affiche la page de connexion si aucun utilisateur n'est connecté, et la page d'accueil s'il y a un utilisateur. Étant donné que cela se produit lorsque l'utilisateur se déconnecte, l'application affichera la page de connexion.

Personnaliser la page de profil

Semblable à la page de connexion, la page de profil est personnalisable. Premièrement, notre page actuelle n'a aucun moyen de revenir à la page d'accueil une fois qu'un utilisateur est sur la page de profil. Corrigez ce problème en attribuant au widget ProfileScreen une AppBar.

maison.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'argument ProfileScreen.appBar accepte un widget AppBar du package Flutter Material, il peut donc être traité comme n'importe quel autre AppBar que vous avez créé et transmis à un Scaffold . Dans cet exemple, la fonctionnalité par défaut d'ajout automatique d'un bouton "retour" est conservée et l'écran a désormais un titre.

Ajouter des enfants à l'écran de profil

Le widget ProfileScreen possède également un argument facultatif nommé enfants. Cet argument accepte une liste de widgets, et ces widgets seront placés verticalement à l'intérieur d'un widget Column déjà utilisé en interne pour créer le ProfileScreen. Ce widget Colonne dans la méthode de construction ProfileScreen placera les enfants que vous lui transmettrez au-dessus du bouton « Déconnexion ».

Mettez à jour le code dans home.dart pour afficher le logo de l'entreprise ici, similaire à l'écran de connexion.

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

Rechargez votre application et vous verrez ceci à l'écran :

ebe5792b765dbf87.png

7. Connexion multiplateforme Google Auth

L'interface utilisateur de FlutterFire fournit également des widgets et des fonctionnalités pour l'authentification auprès de fournisseurs tiers, tels que Google, Twitter, Facebook, Apple et Github.

Pour intégrer l'authentification Google, installez le plugin officiel firebase_ui_oauth_google et ses dépendances, qui géreront le flux d'authentification natif. Dans le terminal, accédez à la racine de votre projet Flutter et entrez la commande suivante :

flutter pub add google_sign_in
flutter pub add firebase_ui_oauth_google

Activer le fournisseur de connexion Google

Ensuite, activez le fournisseur Google dans la console Firebase :

  1. Accédez à l’écran Fournisseurs de connexion d’authentification dans la console.
  2. Cliquez sur "Ajouter un nouveau fournisseur". 8286fb28be94bf30.png
  3. Sélectionnez "Google". c4e28e6f4974be7f.png
  4. Basculez le commutateur intitulé « Activer » et appuyez sur « Enregistrer ». e74ff86990763826.png
  5. Si un modal apparaît avec des informations sur le téléchargement des fichiers de configuration, cliquez sur "Terminé".
  6. Confirmez que le fournisseur de connexion Google a été ajouté. 5329ce0543c90d95.png

Ajouter un bouton de connexion Google

Avec la connexion Google activée, ajoutez le widget nécessaire pour afficher un bouton de connexion Google stylisé sur la page de connexion. Accédez au fichier auth_gate.dart et mettez à jour le code comme suit :

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

Le seul nouveau code ici est l'ajout de GoogleProvider(clientId: "YOUR_WEBCLIENT_ID") à la configuration du widget SignInScreen.

Une fois cela ajouté, rechargez votre application et vous verrez un bouton de connexion Google.

aca71a46a011bfb5.png

Configurer le bouton de connexion

Le bouton ne fonctionne pas sans configuration supplémentaire. Si vous développez avec Flutter Web, c'est la seule étape que vous devez ajouter pour que cela fonctionne. D'autres plates-formes nécessitent des étapes supplémentaires, qui sont abordées dans un instant.

  1. Accédez à la page Fournisseurs d'authentification dans la console Firebase .
  2. Cliquez sur le fournisseur Google. 9b3a325c5eca6e49.png
  3. Cliquez sur le panneau d'extension "Configuration du SDK Web".
  4. Copiez la valeur de « ID client Web » 711a79f0d931c60f.png
  5. Revenez dans votre éditeur de texte, et mettez à jour l'instance de GoogleProvider dans le fichier auth_gate.dart en passant cet ID au paramètre nommé clientId .
GoogleProvider(
   clientId: "YOUR_WEBCLIENT_ID"
)

Une fois l’ID client Web saisi, rechargez votre application. Lorsque vous appuyez sur le bouton « Connectez-vous avec Google », une nouvelle fenêtre apparaît (si vous utilisez le Web) qui vous guide à travers le flux de connexion à Google. Au départ, cela ressemble à ceci :

14e73e3c9de704bb.png

Configurer iOS

Pour que cela fonctionne sur iOS, il existe un processus de configuration supplémentaire.

  1. Accédez à l'écran Paramètres du projet dans la console Firebase . Il y aura une carte répertoriant vos applications Firebase qui ressemble à ceci : fefa674acbf213cc.png
  2. Cliquez sur iOS. Notez que le nom de votre application sera différent du mien. Là où le mien dit "terminé", le vôtre dira "start", si vous avez utilisé le projet flutter-codelabs/firebase-auth-flutterfire-ui/start pour suivre cet atelier de programmation.
  3. Cliquez sur le bouton "GoogleServices-Info.plist" pour télécharger le fichier de configuration nécessaire. f89b3192871dfbe3.png
  4. Faites glisser et déposez le fichier téléchargé dans le répertoire appelé . /ios/Runner dans votre projet Flutter.
  5. Ouvrez Xcode en exécutant la commande de terminal suivante depuis la racine de votre projet :

ouvrez iOS/Runner.xcworkspace

  1. Faites un clic droit sur le répertoire Runner et sélectionnez Ajouter des fichiers à "Runner". 858986063a4c5201.png
  2. Sélectionnez GoogleService-Info.plist dans le gestionnaire de fichiers.
  3. De retour dans votre éditeur de texte (qui n'est pas Xcode), ajoutez les attributs CFBundleURLTypes ci-dessous dans le fichier [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 -->

Si votre application Flutter s'exécute déjà sur iOS, vous devez la fermer complètement, puis réexécuter l'application. Sinon, exécutez l'application sous iOS.

8. Félicitations !

Vous avez terminé l'atelier de programmation Firebase Auth UI pour Flutter. Vous pouvez trouver le code complété pour ce Codelab dans le répertoire "complete" sur github : Flutter Codelabs

Ce que nous avons couvert

  • Configuration d'une application Flutter pour utiliser Firebase
  • Configurer un projet Firebase dans la console Firebase
  • CLI FlutterFire
  • CLI Firebase
  • Utiliser l'authentification Firebase
  • Utiliser l'interface utilisateur FlutterFire pour gérer facilement l'authentification Firebase dans votre application Flutter

Prochaines étapes

Apprendre encore plus

Sparky est là pour célébrer avec vous !

2a0ad195769368b1.gif