Agregue un flujo de autenticación de usuario a una aplicación Flutter usando FirebaseUI

1. Antes de comenzar

En este codelab, aprenderá cómo agregar Firebase Authentication a su aplicación Flutter usando el paquete FlutterFire UI. Con este paquete, agregará autenticación de correo electrónico/contraseña y autenticación de inicio de sesión de Google a una aplicación Flutter. También aprenderá cómo configurar un proyecto de Firebase y usar la CLI de FlutterFire para inicializar Firebase en su aplicación Flutter.

Requisitos previos

Este codelab asume que tienes algo de experiencia con Flutter. De lo contrario, es posible que desees aprender primero los conceptos básicos. Los siguientes enlaces son útiles:

También debes tener algo de experiencia en Firebase, pero está bien si nunca agregaste Firebase a un proyecto de Flutter. Si no está familiarizado con Firebase console o es completamente nuevo en Firebase, consulte primero los siguientes enlaces:

Lo que crearás

Este codelab te guía en la creación del flujo de autenticación para una aplicación Flutter, usando Firebase para la autenticación. La aplicación tendrá una pantalla de inicio de sesión, una pantalla de "Registro", una pantalla de recuperación de contraseña y una pantalla de perfil de usuario.

6604fc9157f2c6ae.pngeab9509a41074930.pngda49189a5838e0bb.pngb2ccfb3632b77878.png

lo que aprenderás

Este codelab cubre:

  • Agregar Firebase a una aplicación Flutter
  • Configuración de la consola Firebase
  • Usar Firebase CLI para agregar Firebase a su aplicación
  • Usando FlutterFire CLI para generar la configuración de Firebase en Dart
  • Agregar autenticación de Firebase a tu aplicación Flutter
  • Configuración de Firebase Authentication en la consola
  • Agregar correo electrónico y contraseña para iniciar sesión con el paquete firebase_ui_auth
  • Agregar registro de usuario con el paquete firebase_ui_auth
  • Agregar un mensaje "¿Olvidaste tu contraseña?" página
  • Agregar el inicio de sesión de Google con firebase_ui_auth
  • Configurar su aplicación para que funcione con múltiples proveedores de inicio de sesión.
  • Agregar una pantalla de perfil de usuario a su aplicación con el paquete firebase_ui_auth

Este codelab se ocupa específicamente de agregar un sistema de autenticación sólido utilizando el paquete firebase_ui_auth . Como verá, toda esta aplicación, con todas las características anteriores, se puede implementar con alrededor de 100 líneas de código.

Lo que necesitarás

  • Conocimiento práctico de Flutter y el SDK instalado.
  • Un editor de texto (Futter admite JetBrains IDE, Android Studio y VS Code)
  • Navegador Google Chrome u otro objetivo de desarrollo preferido para Flutter. (Algunos comandos de terminal en este codelab asumirán que estás ejecutando tu aplicación en Chrome)

2. Crea y configura un proyecto de Firebase

La primera tarea que deberá completar es crear un proyecto de Firebase en la consola web de Firebase.

Crear un proyecto de Firebase

  1. Inicia sesión en Firebase .
  2. En Firebase console, haz clic en Agregar proyecto (o Crear un proyecto ) e ingresa un nombre para tu proyecto de Firebase (por ejemplo, " FlutterFire-UI-Codelab ").

df42a5e3d9584b48.png

  1. Haga clic en las opciones de creación de proyectos. Acepte los términos de Firebase si se le solicita. Omita la configuración de Google Analytics, ya que no utilizará Analytics para esta aplicación.

d1fcec48bf251eaa.png

Para obtener más información sobre los proyectos de Firebase, consulte Comprender los proyectos de Firebase .

La aplicación que estás creando utiliza Firebase Authentication para permitir que tus usuarios inicien sesión en tu aplicación. También permite que nuevos usuarios se registren desde la aplicación Flutter.

La autenticación de Firebase debe habilitarse mediante Firebase Console y necesita una configuración especial una vez habilitada.

Habilite el inicio de sesión por correo electrónico para la autenticación de Firebase

Para permitir que los usuarios inicien sesión en la aplicación web, primero utilizará el método de inicio de sesión por correo electrónico/contraseña . Más adelante, agregará el método de inicio de sesión de Google .

  1. En Firebase console, expanda el menú Construir en el panel izquierdo.
  2. Haga clic en Autenticación y luego haga clic en el botón Comenzar y luego en la pestaña Método de inicio de sesión (o haga clic aquí para ir directamente a la pestaña Método de inicio de sesión ).
  3. Haga clic en Correo electrónico/Contraseña en la lista de proveedores de inicio de sesión , configure el interruptor Habilitar en la posición activado y luego haga clic en Guardar . 58e3e3e23c2f16a4.png

3. Configura la aplicación Flutter

Deberá descargar el código de inicio e instalar Firebase CLI antes de comenzar.

Obtener el código de inicio

Clona el repositorio de GitHub desde la línea de comando:

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

Alternativamente, si tiene instalada la herramienta CLI de GitHub :

gh repo clone flutter/codelabs flutter-codelabs

El código de muestra debe clonarse en el directorio flutter-codelabs de su máquina, que contiene el código para una colección de codelabs. El código para este codelab se encuentra en el subdirectorio flutter-codelabs/firebase-auth-flutterfire-ui .

El directorio flutter-codelabs/firebase-auth-flutterfire-ui contiene dos proyectos de Flutter. Uno se llama complete y el otro se llama start . El directorio start contiene un proyecto incompleto y es donde pasará la mayor parte del tiempo.

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

Si desea avanzar o ver cómo debería verse algo cuando esté completo, busque en el directorio denominado completo para realizar una referencia cruzada.

Si desea seguir el codelab y agregar código usted mismo, debe comenzar con la aplicación Flutter en flutter-codelabs/firebase-auth-flutterfire-ui/start y agregar código a ese proyecto a lo largo del codelab. Abra o importe ese directorio a su IDE preferido.

Instalar Firebase CLI

Firebase CLI proporciona herramientas para administrar sus proyectos de Firebase. La CLI es necesaria para la CLI de FlutterFire, que instalará en un momento.

Hay varias formas de instalar la CLI. La forma más sencilla, si utilizas MacOS o Linux, es ejecutar este comando desde tu terminal:

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

Después de instalar la CLI, debes autenticarte con Firebase.

  1. Inicie sesión en Firebase con su cuenta de Google ejecutando el siguiente comando:
firebase login
  1. Este comando conecta su máquina local a Firebase y le otorga acceso a sus proyectos de Firebase.
  1. Pruebe que la CLI esté instalada correctamente y tenga acceso a su cuenta enumerando sus proyectos de Firebase. Ejecute el siguiente comando:
firebase projects:list
  1. La lista mostrada debe ser la misma que la de los proyectos de Firebase enumerados en Firebase console . Deberías ver al menos flutterfire-ui-codelab.

Instale la CLI de FlutterFire

FlutterFire CLI es una herramienta que ayuda a facilitar el proceso de instalación de Firebase en todas las plataformas compatibles en su aplicación Flutter. Está construido sobre Firebase CLI.

Primero, instale la CLI:

dart pub global activate flutterfire_cli

Asegúrese de que la CLI esté instalada. Ejecute el siguiente comando y asegúrese de que la CLI genere el menú de ayuda.

flutterfire -—help

Agrega tu proyecto de Firebase a tu aplicación Flutter

Configurar FlutterFire

Puedes usar FlutterFire para generar el código Dart necesario para usar Firebase en tu aplicación Flutter.

flutterfire configure

Cuando se ejecuta este comando, se le pedirá que seleccione qué proyecto de Firebase desea usar y qué plataformas desea configurar.

Las siguientes capturas de pantalla muestran las preguntas que deberá responder.

  1. Seleccione el proyecto que desea utilizar. En este caso, utilice flutterfire-ui-codelab 1359cdeb83204baa.png
  2. Seleccione qué plataformas desea utilizar. En este codelab, hay pasos para configurar la autenticación de Firebase para Flutter para web, iOS y Android, pero puedes configurar tu proyecto de Firebase para usar todas las opciones. 301c9534f594f472.png
  3. Esta captura de pantalla muestra el resultado al final del proceso. Si está familiarizado con Firebase, notará que no tuvo que crear aplicaciones de plataforma (por ejemplo, una aplicación de Android) en la consola, y FlutterFire CLI lo hizo por usted. 12199a85ade30459.png

Cuando esto esté completo, mira la aplicación Flutter en tu editor de texto. FlutterFire CLI ha generado un nuevo archivo llamado firebase_options.dart . Este archivo contiene una clase llamada FirebaseOptions, que tiene variables estáticas que contienen la configuración de Firebase necesaria para cada plataforma. Si seleccionó todas las plataformas cuando ejecutó flutterfire configure , verá valores estáticos llamados web , android , ios y 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 usa la palabra aplicación para referirse a una compilación específica para una plataforma específica en un proyecto de Firebase. Por ejemplo, el proyecto de Firebase llamado FlutterFire-ui-codelab tiene múltiples aplicaciones: una para Android, una para iOS, una para MacOS y una para Web.

El método DefaultFirebaseOptions.currentPlatform utiliza la enumeración TargetPlatform expuesta por Flutter para detectar la plataforma en la que se ejecuta su aplicación y luego devuelve los valores de configuración de Firebase necesarios para la aplicación de Firebase correcta.

Agregue paquetes de Firebase a la aplicación Flutter

El último paso de configuración es agregar los paquetes de Firebase relevantes a su proyecto Flutter. El archivo firebase_options.dart debería tener errores porque depende de paquetes de Firebase que aún no se han agregado. En la terminal, asegúrate de estar en la raíz del proyecto Flutter en flutter-codelabs/firebase-emulator-suite/start . Luego, ejecute los tres comandos siguientes:

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

Estos son los únicos paquetes que necesita en este momento.

Inicializar base de fuego

Para utilizar los paquetes agregados y DefaultFirebaseOptions.currentPlatform, actualice el código en la función main en el archivo main.dart .

dardo.principal

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


 runApp(const MyApp());
}

Este código hace dos cosas.

  1. WidgetsFlutterBinding.ensureInitialized() le dice a Flutter que no comience a ejecutar el código del widget de la aplicación hasta que el marco de Flutter esté completamente iniciado. Firebase utiliza canales de plataforma nativos, que requieren que el marco se esté ejecutando.
  2. Firebase.initializeApp configura una conexión entre tu aplicación Flutter y tu proyecto de Firebase. DefaultFirebaseOptions.currentPlatform se importa desde nuestro archivo firebase_options.dart generado. Este valor estático detecta en qué plataforma estás ejecutando y pasa las claves de Firebase correspondientes.

4. Agregue la página de autenticación inicial de Firebase UI

Firebase UI para Auth proporciona widgets que representan pantallas completas en su aplicación. Estas pantallas manejan diferentes flujos de autenticación en toda su aplicación, como inicio de sesión, registro, olvidé mi contraseña, perfil de usuario y más. Para comenzar, agregue una página de inicio a su aplicación que actúe como un protector de autenticación para la aplicación principal.

Aplicación Material o Cupertino

La interfaz de usuario de FlutterFire requiere que su aplicación esté empaquetada en MaterialApp o CupertinoApp. Dependiendo de su elección, la interfaz de usuario reflejará automáticamente las diferencias entre los widgets Material o Cupertino. Para este codelab, use MaterialApp , que ya está agregado a la aplicación en app.dart .

aplicación.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(),
   );
 }
}

Verificar el estado de autenticación

Antes de poder mostrar una pantalla de inicio de sesión, debe determinar si el usuario está actualmente autenticado. La forma más común de verificar esto es escuchar authStateChanges de FirebaseAuth usando el complemento Firebase Auth .

En el ejemplo de código anterior, MaterialApp está creando un widget AuthGate en su método de compilación. (Este es un widget personalizado, no proporcionado por la interfaz de usuario de FlutterFire).

Ese widget debe actualizarse para incluir la secuencia authStateChanges .

La API authStateChanges devuelve una Stream con el usuario actual (si ha iniciado sesión) o nula si no lo está. Para suscribirse a este estado en nuestra aplicación, puede usar el widget StreamBuilder de Flutter y pasarle la transmisión.

StreamBuilder es un widget que se construye a sí mismo basándose en la última instantánea de datos de un Stream que le pasa. Se reconstruye automáticamente cuando Stream emite una nueva instantánea.

Actualice el código en 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();
      },
    );
  }
}
  • Se pasa StreamBuilder.stream FirebaseAuth.instance.authStateChanged , la secuencia antes mencionada, que devolverá un objeto User de Firebase si el usuario se ha autenticado. (De lo contrario, devolverá null ).
  • A continuación, el código utiliza snapshot.hasData para comprobar si el valor de la secuencia contiene el objeto User .
  • Si no lo hay, devolverá un widget SignInScreen . Actualmente, esa pantalla no hará nada. Esto se actualizará en el siguiente paso.
  • De lo contrario, devuelve una HomeScreen , que es la parte principal de la aplicación a la que solo pueden acceder los usuarios autenticados.

SignInScreen es un widget que proviene del paquete FlutterFire UI. Este será el foco del siguiente paso de este codelab. Cuando ejecute la aplicación en este punto, debería ver una pantalla de inicio de sesión en blanco.

5. Pantalla de inicio de sesión

El widget SignInScreen , proporcionado por FlutterFire UI, agrega la siguiente funcionalidad:

  • Permite a los usuarios iniciar sesión
  • Si los usuarios olvidaron su contraseña, pueden tocar "¿Olvidaste tu contraseña?" y ser llevado a un formulario para restablecer su contraseña
  • Si un usuario aún no está registrado, puede tocar "Registrarse" y acceder a otro formulario que le permita registrarse.

Nuevamente, esto requiere sólo un par de líneas de código. Recuerde el código en el 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();
      },
    );
  }
}

El widget SignInScreen y su argumento providers es el único código necesario para obtener todas las funciones antes mencionadas. Ahora debería ver una pantalla de inicio de sesión que tiene entradas de texto "correo electrónico" y "contraseña", así como un botón "Iniciar sesión".

Si bien es funcional, carece de estilo. El widget expone parámetros para personalizar la apariencia de la pantalla de inicio de sesión. Por ejemplo, es posible que desee agregar el logotipo de su empresa.

Personaliza la pantalla de inicio de sesión

encabezadoConstructor

Con el argumento SignInScreen.headerBuilder , puede agregar los widgets que desee encima del formulario de inicio de sesión. Actualice el archivo auth_gate.dart con este código:

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

El argumento headerBuilder requiere una función del tipo HeaderBuilder, que está definida en el paquete de interfaz de usuario de FlutterFire.

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

Debido a que es una devolución de llamada, expone valores que podría usar, como BuildContext y BoxConstraints , y requiere que devuelva un widget. Cualquiera que sea el widget que devuelva se muestra en la parte superior de la pantalla. En este ejemplo, el nuevo código agrega una imagen en la parte superior de la pantalla. Su aplicación ahora debería verse así.

73d7548d91bbd2ab.png

Generador de subtítulos

La pantalla de inicio de sesión expone tres parámetros adicionales que le permiten personalizar la pantalla: subtitleBuilder , footerBuilder y sideBuilder .

El subtitleBuilder es ligeramente diferente en que los argumentos de devolución de llamada incluyen una acción, que es de tipo AuthAction . AuthAction es una enumeración que puede utilizar para detectar si la pantalla en la que se encuentra el usuario es la pantalla de "iniciar sesión" o la pantalla de "registro".

Actualice el código en auth_gate.dart para usar 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();
     },
   );
 }
}

Vuelva a cargar la aplicación y debería verse así

El argumento footerBuilder es el mismo que el subtitleBuilder. No expone BoxConstraints ni shrinkOffset , ya que está destinado a texto en lugar de imágenes. (Aunque puedes agregar cualquier widget que desees).

Agregue un pie de página a su pantalla de inicio de sesión con este código.

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

Constructor lateral

El argumento SignInScreen.sidebuilder acepta una devolución de llamada y esta vez los argumentos de esa devolución de llamada son BuildContext y double shrinkOffset . El widget que devuelve sideBuilder se mostrará a la izquierda del formulario de inicio de sesión y solo en pantallas anchas. Efectivamente, eso significa que el widget solo se mostrará en aplicaciones web y de escritorio.

Internamente, la interfaz de usuario de FlutterFire utiliza un punto de interrupción para determinar si se debe mostrar el contenido del encabezado (en pantallas altas, como dispositivos móviles) o el contenido lateral (en pantallas anchas, de escritorio o web). Específicamente, si una pantalla tiene más de 800 píxeles de ancho, se muestra el contenido del generador lateral y no el contenido del encabezado. Si la pantalla tiene menos de 800 píxeles de ancho, ocurre lo contrario.

Actualice el código en auth_gate.dart para agregar 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();
     },
   );
 }
}

Tu aplicación ahora debería verse así cuando expandas el ancho de la ventana (si estás usando Flutter web o MacOS).

8dc60b4e5d7dd2d0.png

Crear un usuario

En este punto, todo el código para esta pantalla está listo. Sin embargo, antes de poder iniciar sesión, debe crear un usuario. Puede hacer esto con la pantalla "Registrarse" o puede crear un usuario en Firebase console.

Para usar la consola:

  1. Vaya a la tabla "Usuarios" en Firebase console.
  2. haga clic aquí
  3. Seleccione 'flutterfire-ui-codelab' (u otro proyecto si usó un nombre diferente). Verás esta tabla:

f038fd9a58ed60d9.png

  1. Haga clic en el botón "Agregar usuario".

2d78390d4c5dbbfa.png

  1. Ingrese una dirección de correo electrónico y una contraseña para el nuevo usuario. Esto puede ser un correo electrónico y una contraseña falsos, como los que ingresé en la imagen a continuación. Eso funcionará, pero la función "Olvidé mi contraseña" no funcionará si utiliza una dirección de correo electrónico falsa.

62ba0feb33d54add.png

  1. Haga clic en "Agregar usuario"

32b236b3ef94d4c7.png

Ahora, puede regresar a su aplicación Flutter e iniciar sesión como usuario a través de la página de inicio de sesión. Tu aplicación debería verse así:

dd43d260537f3b1a.png

6. Pantalla de perfil

FlutterFire UI también proporciona un widget ProfileScreen , que nuevamente le brinda muchas funciones en unas pocas líneas de código.

Agregar widget de pantalla de perfil

Navegue hasta el archivo home.dart en su editor de texto. Actualízalo con este código:

casa.dardo

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

El nuevo código destacable es la devolución de llamada pasada al IconButton.isPressed method. Cuando se presiona ese IconButton , su aplicación crea una nueva ruta anónima y navega hacia ella. Esa ruta mostrará el widget ProfileScreen , que se devuelve desde la devolución de llamada MaterialPageRoute.builder .

Vuelva a cargar su aplicación y presione el ícono en la esquina superior derecha (en la barra de aplicaciones) y se mostrará una página como esta:

36487fc4ab4f26a7.png

Esta es la interfaz de usuario estándar proporcionada por la página de interfaz de usuario de FlutterFire. Todos los botones y campos de texto están conectados a Firebase Auth y funcionan de inmediato. Por ejemplo, puedes ingresar un nombre en el campo de texto "Nombre" y FlutterFire UI llamará al método FirebaseAuth.instance.currentUser?.updateDisplayName , que guardará ese nombre en Firebase.

Cerrando sesión

En este momento, si presiona el botón "Cerrar sesión", la aplicación no cambiará. Cerrará su sesión, pero no volverá al widget de AuthGate. Para implementar esto, use el parámetro ProfileScreen.actions.

Primero, actualice el código en home.dart.

casa.dardo

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

Ahora, cuando crea una instancia de ProfileScreen , también le pasa una lista de acciones al argumento ProfileScreen.actions . Estas acciones son del tipo FlutterFireUiAction . Hay muchas clases diferentes que son subtipos de FlutterFireUiAction y, en general, las usas para decirle a tu aplicación que reaccione a diferentes cambios de estado de autenticación. SignedOutAction llama a una función de devolución de llamada que usted le proporciona cuando el estado de autenticación de Firebase cambia y el usuario actual es nulo.

Al agregar una devolución de llamada que llama a Navigator.of(context).pop() cuando se activa SignedOutAction, la aplicación navegará a la página anterior. En esta aplicación de ejemplo, solo hay una ruta permanente, que muestra la página de inicio de sesión si no hay ningún usuario que haya iniciado sesión y la página de inicio si hay un usuario. Debido a que esto sucede cuando el usuario cierra sesión, la aplicación mostrará la página de inicio de sesión.

Personaliza la página de perfil

Al igual que la página de inicio de sesión, la página de perfil es personalizable. Primero, nuestra página actual no tiene forma de volver a la página de inicio una vez que un usuario está en la página de perfil. Solucione este problema dándole al widget ProfileScreen una AppBar.

casa.dardo

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

El argumento ProfileScreen.appBar acepta un widget AppBar del paquete Flutter Material, por lo que puede tratarse como cualquier otra AppBar que haya creado y pasado a un Scaffold . En este ejemplo, se mantiene la funcionalidad predeterminada de agregar automáticamente un botón "atrás" y la pantalla ahora tiene un título.

Agregar niños a la pantalla de perfil

El widget ProfileScreen también tiene un argumento opcional llamado hijos. Este argumento acepta una lista de widgets, y esos widgets se colocarán verticalmente dentro de un widget de columna que ya se usa internamente para crear ProfileScreen. Este widget de columna en el método de compilación ProfileScreen colocará a los elementos secundarios que le pase encima del botón "Cerrar sesión".

Actualice el código en home.dart para mostrar el logotipo de la empresa aquí, similar a la pantalla de inicio de sesión.

casa.dardo

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

Vuelve a cargar tu aplicación y verás esto en la pantalla:

ebe5792b765dbf87.png

7. Inicio de sesión de autenticación de Google multiplataforma

FlutterFire UI también proporciona widgets y funciones para autenticarse con proveedores externos, como Google, Twitter, Facebook, Apple y Github.

Para integrarse con la autenticación de Google, instale el complemento oficial firebase_ui_oauth_google y sus dependencias, que manejarán el flujo de autenticación nativo. En la terminal, navegue hasta la raíz de su proyecto flutter e ingrese el siguiente comando:

flutter pub add google_sign_in
flutter pub add firebase_ui_oauth_google

Habilitar proveedor de inicio de sesión de Google

A continuación, habilite el proveedor de Google en Firebase Console :

  1. Navegue hasta la pantalla Proveedores de inicio de sesión de autenticación en la consola.
  2. Haga clic en "Agregar nuevo proveedor". 8286fb28be94bf30.png
  3. Seleccione "Google". c4e28e6f4974be7f.png
  4. Mueva el interruptor con la etiqueta "Habilitar" y presione "Guardar". e74ff86990763826.png
  5. Si aparece un modal con información sobre la descarga de archivos de configuración, haga clic en "Listo".
  6. Confirme que se haya agregado el proveedor de inicio de sesión de Google. 5329ce0543c90d95.png

Agregar botón de inicio de sesión de Google

Con el inicio de sesión de Google habilitado, agregue el widget necesario para mostrar un botón de inicio de sesión de Google estilizado en la página de inicio de sesión. Navegue hasta el archivo auth_gate.dart y actualice el código a lo siguiente:

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

El único código nuevo aquí es la adición de GoogleProvider(clientId: "YOUR_WEBCLIENT_ID") a la configuración del widget SignInScreen.

Una vez agregado, vuelva a cargar su aplicación y verá un botón de inicio de sesión de Google.

aca71a46a011bfb5.png

Configurar el botón de inicio de sesión

El botón no funciona sin una configuración adicional. Si estás desarrollando con Flutter Web, este es el único paso que debes agregar para que funcione. Otras plataformas requieren pasos adicionales, que se analizan más adelante.

  1. Navegue a la página Proveedores de autenticación en Firebase Console .
  2. Haga clic en el proveedor de Google. 9b3a325c5eca6e49.png
  3. Haga clic en el panel de expansión "Configuración del SDK web".
  4. Copie el valor de 'ID de cliente web' 711a79f0d931c60f.png
  5. Regrese a su editor de texto y actualice la instancia de GoogleProvider en el archivo auth_gate.dart pasando esta ID al parámetro denominado clientId .
GoogleProvider(
   clientId: "YOUR_WEBCLIENT_ID"
)

Una vez ingresada la ID del cliente web, recarga tu aplicación. Cuando presionas el botón "Iniciar sesión con Google", aparecerá una nueva ventana (si estás usando la web) que te guiará a través del flujo de inicio de sesión de Google. Inicialmente, se ve así:

14e73e3c9de704bb.png

Configurar iOS

Para que esto funcione en iOS, existe un proceso de configuración adicional.

  1. Navegue a la pantalla Configuración del proyecto en Firebase console . Habrá una tarjeta que enumera tus aplicaciones de Firebase y se ve así: fefa674acbf213cc.png
  2. Haga clic en iOS. Tenga en cuenta que el nombre de su aplicación será diferente al mío. Donde el mío dice "completar", el tuyo dirá "iniciar", si usaste el proyecto flutter-codelabs/firebase-auth-flutterfire-ui/start para seguir este codelab.
  3. Haga clic en el botón que dice "GoogleServices-Info.plist" para descargar el archivo de configuración necesario. f89b3192871dfbe3.png
  4. Arrastre y suelte el archivo descargado en el directorio llamado . /ios/Runner en tu proyecto Flutter.
  5. Abra Xcode ejecutando el siguiente comando de terminal desde la raíz de su proyecto:

abra ios/Runner.xcworkspace

  1. Haga clic derecho en el directorio de Runner y seleccione Agregar archivos a "Runner". 858986063a4c5201.png
  2. Seleccione GoogleService-Info.plist en el administrador de archivos.
  3. De vuelta en su editor de texto (que no es Xcode), agregue los atributos CFBundleURLTypes a continuación en el archivo [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 su aplicación Flutter ya se está ejecutando en iOS, debe cerrarla por completo y luego volver a ejecutar la aplicación. De lo contrario, ejecute la aplicación en iOS.

8. ¡Felicitaciones!

Has completado la interfaz de usuario de autenticación de Firebase para el codelab de Flutter. Puede encontrar el código completo para este Codelab en el directorio "completo" en github: Flutter Codelabs

Lo que hemos cubierto

  • Configurar una aplicación Flutter para usar Firebase
  • Configurar un proyecto de Firebase en Firebase console
  • CLI de FlutterFire
  • CLI de base de fuego
  • Usando la autenticación de Firebase
  • Uso de la interfaz de usuario de FlutterFire para manejar fácilmente la autenticación de Firebase en su aplicación Flutter

Próximos pasos

Aprende más

¡Sparky está aquí para celebrar contigo!

2a0ad195769368b1.gif