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:
- Haga un recorrido por el marco de widgets de Flutter
- Prueba el codelab Escribe tu primera aplicación Flutter, parte 1
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.
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
- Inicia sesión en Firebase .
- 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 ").
- 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.
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 .
- En Firebase console, expanda el menú Construir en el panel izquierdo.
- 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 ).
- 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 .
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.
- Inicie sesión en Firebase con su cuenta de Google ejecutando el siguiente comando:
firebase login
- Este comando conecta su máquina local a Firebase y le otorga acceso a sus proyectos de Firebase.
- 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
- 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.
- Seleccione el proyecto que desea utilizar. En este caso, utilice
flutterfire-ui-codelab
- 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.
- 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.
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.
-
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. -
Firebase.initializeApp
configura una conexión entre tu aplicación Flutter y tu proyecto de Firebase.DefaultFirebaseOptions.currentPlatform
se importa desde nuestro archivofirebase_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 objetoUser
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 objetoUser
. - 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í.
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í
Generador de pie de página
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).
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:
- Vaya a la tabla "Usuarios" en Firebase console.
- haga clic aquí
- Seleccione 'flutterfire-ui-codelab' (u otro proyecto si usó un nombre diferente). Verás esta tabla:
- Haga clic en el botón "Agregar usuario".
- 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.
- Haga clic en "Agregar usuario"
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í:
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:
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:
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 :
- Navegue hasta la pantalla Proveedores de inicio de sesión de autenticación en la consola.
- Haga clic en "Agregar nuevo proveedor".
- Seleccione "Google".
- Mueva el interruptor con la etiqueta "Habilitar" y presione "Guardar".
- Si aparece un modal con información sobre la descarga de archivos de configuración, haga clic en "Listo".
- Confirme que se haya agregado el proveedor de inicio de sesión de Google.
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.
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.
- Navegue a la página Proveedores de autenticación en Firebase Console .
- Haga clic en el proveedor de Google.
- Haga clic en el panel de expansión "Configuración del SDK web".
- Copie el valor de 'ID de cliente web'
- Regrese a su editor de texto y actualice la instancia de
GoogleProvider
en el archivoauth_gate.dart
pasando esta ID al parámetro denominadoclientId
.
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í:
Configurar iOS
Para que esto funcione en iOS, existe un proceso de configuración adicional.
- Navegue a la pantalla Configuración del proyecto en Firebase console . Habrá una tarjeta que enumera tus aplicaciones de Firebase y se ve así:
- 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. - Haga clic en el botón que dice "GoogleServices-Info.plist" para descargar el archivo de configuración necesario.
- Arrastre y suelte el archivo descargado en el directorio llamado .
/ios/Runner
en tu proyecto Flutter. - Abra Xcode ejecutando el siguiente comando de terminal desde la raíz de su proyecto:
abra ios/Runner.xcworkspace
- Haga clic derecho en el directorio de Runner y seleccione Agregar archivos a "Runner".
- Seleccione GoogleService-Info.plist en el administrador de archivos.
- 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
- Obtenga más información sobre el uso de Firestore y la autenticación en Flutter: conozca Firebase para Flutter Codelab
- Explora otras herramientas de Firebase para crear tu aplicación Flutter:
- Almacenamiento en la nube
- Funciones de la nube
- Base de datos en tiempo real
Aprende más
- Sitio de Firebase: firebase.google.com
- Sitio de aleteo: flutter.dev
- FlutterFire Firebase Widgets de Flutter: firebase.flutter.dev
- Canal de YouTube de Firebase
- Canal de YouTube de aleteo
¡Sparky está aquí para celebrar contigo!