1. Antes de começar
Neste codelab, você aprenderá a adicionar o Firebase Authentication ao seu app do Flutter usando o pacote de interface do FlutterFire. Com esse pacote, você vai adicionar a autenticação por e-mail/senha e a autenticação de Login do Google a um app do Flutter. Você também aprenderá a configurar um projeto do Firebase e a usar a CLI do FlutterFire para inicializar o Firebase no seu app criado com o Flutter.
Pré-requisitos
Este codelab presume que você tem alguma experiência com o Flutter. Caso contrário, talvez você queira primeiro aprender o básico. Confira alguns links úteis:
- Faça um tour do framework do widget do Flutter
- Teste o codelab Criar seu primeiro app do Flutter, parte 1
Você também deve ter alguma experiência com o Firebase, mas não tem problema se você nunca adicionou o Firebase a um projeto Flutter. Se você não conhece o console do Firebase ou é completamente novo no Firebase, primeiro consulte os links a seguir:
O que você vai criar
Este codelab orienta você na criação do fluxo de autenticação para um app Flutter usando o Firebase para Authentication. O aplicativo terá uma tela de login, uma tela de registro, uma tela de recuperação de senha e uma tela de perfil do usuário.
Conteúdo
Este codelab abrange:
- Como adicionar o Firebase a um app do Flutter
- Configuração do Console do Firebase
- Como usar a CLI do Firebase para adicionar o Firebase ao aplicativo
- Usar a CLI do FlutterFire para gerar configurações do Firebase no Dart
- Como adicionar o Firebase Authentication ao seu app do Flutter
- Configuração do Firebase Authentication no console
- Como adicionar login com e-mail e senha com o pacote
firebase_ui_auth
- Como adicionar o registro de usuário com o pacote
firebase_ui_auth
- Como adicionar uma página "Esqueceu a senha?"
- Adicionando o Login do Google com
firebase_ui_auth
- Configurar o app para funcionar com vários provedores de login.
- Como adicionar uma tela de perfil de usuário ao aplicativo com o pacote
firebase_ui_auth
Este codelab trata especificamente de adicionar um sistema robusto de autenticação usando o pacote firebase_ui_auth
. Como você verá, o app inteiro, com todos os recursos acima, pode ser implementado com cerca de cem linhas de código.
Pré-requisitos
- Conhecimento prático do Flutter (link em inglês) e do SDK instalado.
- Um editor de texto (ambientes de desenvolvimento integrado do JetBrains, o Android Studio e o VS Code são compatíveis com o Flutter).
- o navegador Google Chrome ou outra plataforma de desenvolvimento preferencial para o Flutter; Alguns comandos de terminal neste codelab presumem que você está executando o app no Chrome.
2. Criar e configurar um projeto do Firebase
A primeira tarefa que você precisa realizar é criar um projeto do Firebase no console da Web do Firebase.
criar um projeto do Firebase
- Faça login no Firebase.
- No Console do Firebase, clique em Adicionar projeto (ou Criar um projeto) e digite um nome para ele (por exemplo, FlutterFire-UI-Codelab).
- Clique nas opções de criação do projeto. Se solicitado, aceite os termos do Firebase. Pular a configuração do Google Analytics, porque ele não vai ser usado neste app.
Para saber mais sobre os projetos do Firebase, consulte Noções básicas sobre os projetos do Firebase.
O app que você está criando usa o Firebase Authentication para permitir que os usuários façam login no app e que novos usuários se registrem pelo aplicativo Flutter.
O Firebase Authentication precisa ser ativado usando o Console do Firebase e precisa de configuração especial depois de ativado.
Ativar o login por e-mail para o Firebase Authentication
Para permitir que os usuários façam login no app da Web, primeiro você precisa usar o método de login de E-mail/senha. Mais tarde, você vai adicionar o método de Login do Google.
- No Console do Firebase, expanda o menu Build no painel esquerdo.
- Clique em Autenticação e, em seguida, no botão Primeiros passos e na guia Método de login (ou clique aqui para acessar a guia Método de login).
- Clique em E-mail/senha na lista Provedores de login, ative a opção Ativar e clique em Salvar.
3. Configurar o app do Flutter
Antes de começar, faça o download do código inicial e instale a CLI do Firebase.
Acessar o código inicial
Clone o repositório do GitHub (link em inglês) da linha de comando:
git clone https://github.com/flutter/codelabs.git flutter-codelabs
Como alternativa, se você tiver a ferramenta CLI do GitHub instalada:
gh repo clone flutter/codelabs flutter-codelabs
O exemplo de código precisa ser clonado no diretório flutter-codelabs
da máquina, que contém o código de uma coleção de codelabs. O código deste codelab está no subdiretório flutter-codelabs/firebase-auth-flutterfire-ui
.
O diretório flutter-codelabs/firebase-auth-flutterfire-ui
contém dois projetos do Flutter. Um é chamado de complete
, e o outro é chamado de start
. O diretório start
contém um projeto incompleto, e é nele que você vai passar a maior parte do tempo.
cd flutter-codelabs/firebase-auth-flutterfire-ui/start
Se você quiser avançar ou ver como algo deve ficar quando completo, procure no diretório chamado complete para fazer referência cruzada.
Se você quiser acompanhar o codelab e adicionar código por conta própria, comece com o app do Flutter em flutter-codelabs/firebase-auth-flutterfire-ui/start
e adicione código a esse projeto ao longo do codelab. Abra ou importe esse diretório para o ambiente de desenvolvimento integrado de sua preferência.
Instalar a CLI do Firebase
A CLI do Firebase oferece ferramentas para gerenciar seus projetos do Firebase. A CLI é necessária para a CLI do FlutterFire, que você instalará em breve.
Há várias maneiras de instalar a CLI. A maneira mais simples, se você estiver usando o MacOS ou o Linux, é executar este comando no seu terminal:
curl -sL https://firebase.tools | bash
Depois de instalar a CLI, faça a autenticação com o Firebase.
- Faça login no Firebase com sua Conta do Google executando o seguinte comando:
firebase login
- Esse comando conecta sua máquina local ao Firebase e concede acesso aos seus projetos do Firebase.
- Liste seus projetos do Firebase para testar se a CLI está instalada corretamente e tem acesso à conta. Execute este comando:
firebase projects:list
- A lista exibida precisa conter os mesmos projetos do Firebase listados no Console do Firebase. Deve haver pelo menos
flutterfire-ui-codelab.
Instalar a CLI do FlutterFire
A CLI do FlutterFire é uma ferramenta que facilita o processo de instalação do Firebase em todas as plataformas compatíveis com seu app do Flutter. Ela é baseada na CLI do Firebase.
Primeiro, instale a CLI:
dart pub global activate flutterfire_cli
Verifique se a CLI foi instalada. Execute o comando a seguir e verifique se a CLI gera o menu de ajuda.
flutterfire -—help
Adicionar seu projeto do Firebase ao app Flutter
Configurar o FlutterFire
É possível usar o FlutterFire para gerar o código Dart necessário para usar o Firebase no seu app criado com o Flutter.
flutterfire configure
Quando esse comando é executado, você precisa selecionar qual projeto do Firebase quer usar e quais plataformas quer configurar.
As capturas de tela abaixo mostram as solicitações que você precisa responder.
- Selecione o projeto que você quer usar. Nesse caso, use
flutterfire-ui-codelab
. - Selecione as plataformas que você quer usar. Neste codelab, existem etapas para configurar o Firebase Authentication para Flutter na Web, iOS e Android, mas você pode configurar seu projeto do Firebase para usar todas as opções.
- Esta captura de tela mostra a saída no final do processo. Se estiver familiarizado com o Firebase, você perceberá que não era necessário criar aplicativos de plataforma (por exemplo, um aplicativo Android) no console, e que a CLI do FlutterFire fez isso por você.
Quando isso terminar, observe o app do Flutter no seu editor de texto. A CLI do FlutterFire gerou um novo arquivo chamado firebase_options.dart
. Esse arquivo contém uma classe chamada FirebaseOptions, que tem variáveis estáticas que mantêm a configuração do Firebase necessária para cada plataforma. Se você tiver selecionado todas as plataformas ao executar flutterfire configure
, verá valores estáticos chamados web
, android
, ios
e macos
.
firebase_options.dart (link em inglês)
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',
);
}
O Firebase usa o termo "aplicativo" para se referir a um build específico de uma plataforma em um projeto do Firebase. Por exemplo, o projeto do Firebase chamado FlutterFire-ui-codelab tem vários aplicativos: um para Android, um para iOS, um para MacOS e um para a Web.
O método DefaultFirebaseOptions.currentPlatform
usa a enumeração TargetPlatform
exposta pelo Flutter para detectar a plataforma em que o app está sendo executado e retorna os valores de configuração do Firebase necessários para o aplicativo correto.
Adicionar pacotes do Firebase ao app Flutter
A etapa final de configuração é adicionar os pacotes relevantes do Firebase ao seu projeto do Flutter. O arquivo firebase_options.dart
vai conter erros porque depende de pacotes do Firebase que ainda não foram adicionados. No terminal, verifique se você está na raiz do projeto Flutter em flutter-codelabs/firebase-emulator-suite/start
. Em seguida, execute os três comandos a seguir:
flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add firebase_ui_auth
Esses são os únicos pacotes que você precisa no momento.
Inicializar o Firebase
Para usar os pacotes adicionados e o DefaultFirebaseOptions.currentPlatform,
, atualize o código na função main
no arquivo main.dart
.
main.dart (link em inglês)
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}
Esse código faz duas coisas.
WidgetsFlutterBinding.ensureInitialized()
instrui o Flutter a não começar a executar o código do widget do aplicativo até que o framework do Flutter seja completamente inicializado. O Firebase usa canais de plataforma nativos, que exigem que o framework esteja em execução.- O
Firebase.initializeApp
configura uma conexão entre o app Flutter e o projeto do Firebase. ODefaultFirebaseOptions.currentPlatform
é importado do arquivofirebase_options.dart
gerado. Esse valor estático detecta em qual plataforma você está sendo executado e transmite as chaves do Firebase correspondentes.
4. Adicionar página inicial de autenticação da interface do Firebase
A interface do Firebase para Auth fornece widgets que representam telas inteiras no seu aplicativo. Essas telas lidam com diferentes fluxos de autenticação em todo o aplicativo, como Login, Registro, Esqueci a senha, Perfil do usuário e muito mais. Para começar, adicione ao seu aplicativo uma página de destino que atue como uma proteção de autenticação para o aplicativo principal.
App Material ou Cupertino
A interface do FlutterFire exige que seu aplicativo seja unido a um MaterialApp ou CupertinoApp. Dependendo da sua escolha, a interface vai refletir automaticamente as diferenças dos widgets do Material Design ou da Cupertino. Neste codelab, use MaterialApp
, que já foi adicionado ao app em app.dart
.
app.dart (link em inglês)
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 o estado da autenticação
Antes de exibir uma tela de login, você precisa determinar se o usuário está autenticado. A maneira mais comum de verificar isso é detectar o authStateChanges do FirebaseAuth usando o plug-in do Firebase Auth.
No exemplo de código acima, o MaterialApp
está criando um widget AuthGate
no método de build. Esse é um widget personalizado, não fornecido pela interface do FlutterFire.
Esse widget precisa ser atualizado para incluir o fluxo authStateChanges
.
A API authStateChanges
retorna um Stream
com o usuário atual (se ele tiver feito login) ou nulo se ele não estiver conectado. Para se inscrever nesse estado no nosso aplicativo, você pode usar o widget StreamBuilder do Flutter e transmitir o stream para ele.
O StreamBuilder
é um widget criado com base no snapshot mais recente dos dados de um stream transmitido. Ele é recriado automaticamente quando o stream emite um novo snapshot.
Atualize o código em auth_gate.dart
.
auth_gate.dart (link em inglês)
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á sendo transmitido paraFirebaseAuth.instance.authStateChanged
, o fluxo mencionado, que retornará um objetoUser
do Firebase se o usuário tiver feito a autenticação. Caso contrário, retornaránull
.- Em seguida, o código usa
snapshot.hasData
para verificar se o valor do stream contém o objetoUser
. - Se não houver, ele vai retornar um widget
SignInScreen
. Atualmente, essa tela não faz nada. Isso será atualizado na próxima etapa. - Caso contrário, ele retorna um
HomeScreen
, que é a parte principal do aplicativo que só os usuários autenticados podem acessar.
O SignInScreen
é um widget do pacote de interface do FlutterFire. Esse será o foco da próxima etapa deste codelab. Ao executar o app nesse momento, você verá uma tela de login em branco.
5. Tela de login
O widget SignInScreen
, fornecido pela interface do FlutterFire, adiciona a seguinte funcionalidade:
- Permite que os usuários façam login
- Se os usuários esquecerem a senha, eles poderão tocar em "Esqueceu a senha?" e serão direcionados a um formulário de redefinição.
- Se um usuário ainda não estiver registrado, ele poderá tocar em "Registrar" e ser direcionado para outro formulário que permita a inscrição.
Novamente, isso requer apenas algumas linhas de código. Retorne ao código no widget AuthGate:
auth_gate.dart (link em inglês)
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();
},
);
}
}
O widget SignInScreen
e o argumento providers
dele são o único código necessário para acessar toda a funcionalidade mencionada. Você verá uma tela de login com entradas de texto "e-mail" e "senha", além do botão "Fazer login".
Embora funcional, ele não tem estilo. O widget expõe parâmetros para personalizar a aparência da tela de login. Por exemplo, você pode adicionar o logotipo da sua empresa.
Personalizar a tela de login
cabeçalho
Com o argumento SignInScreen.headerBuilder
, você pode adicionar os widgets que quiser acima do formulário de login. Atualize o arquivo auth_gate.dart
com este código:
auth_gate.dart (link em inglês)
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();
},
);
}
}
O argumento headerBuilder requer uma função do tipo HeaderBuilder, que é definida no pacote de interface do FlutterFire.
typedef HeaderBuilder = Widget Function(
BuildContext context,
BoxConstraints constraints,
double shrinkOffset,
);
Por ser um callback, ele expõe valores que podem ser usados, como BuildContext
e BoxConstraints
, e exige que você retorne um widget. O widget retornado será exibido na parte superior da tela. Neste exemplo, o novo código adiciona uma imagem à parte de cima da tela. Agora, o aplicativo deve ficar assim:
Criador de legendas
A tela de login expõe três outros parâmetros que permitem personalizar a tela: subtitleBuilder
, footerBuilder
e sideBuilder
.
O subtitleBuilder
é um pouco diferente, porque os argumentos de callback incluem uma ação, que é do tipo AuthAction
. AuthAction
é uma enumeração que pode ser usada para detectar se a tela em que o usuário está é a de "login" ou "registro".
Atualize o código em auth_gate.dart para usar o subtitleBuilder.
auth_gate.dart (link em inglês)
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();
},
);
}
}
Atualize o aplicativo. Ele ficará assim:
Criador de rodapé
O argumento footerBuilder é o mesmo que o subtitleBuilder. Ele não expõe BoxConstraints
ou shrinkOffset
, já que ele é destinado a texto em vez de imagens. No entanto, você pode adicionar o widget que quiser.
Adicione um rodapé à tela de login com este código.
auth_gate.dart (link em inglês)
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();
},
);
}}
Criador lateral
O argumento SignInScreen.sidebuilder aceita um callback e, desta vez, os argumentos são BuildContext
e double shrinkOffset
. O widget que o sideBuilder retorna será exibido à esquerda do formulário de login e apenas em telas grandes. Na verdade, isso significa que o widget será exibido apenas em apps da Web e de computador.
Internamente, a interface do FlutterFire usa um ponto de interrupção para determinar se o conteúdo do cabeçalho precisa ser mostrado (em telas altas, como em dispositivos móveis) ou o conteúdo lateral precisa ser mostrado (em telas widescreen, computadores ou Web). Especificamente, se uma tela tiver mais de 800 pixels de largura, o conteúdo do criador lateral será mostrado, mas o cabeçalho não. Se a tela tiver menos de 800 pixels de largura, o oposto será verdadeiro.
Atualize o código em auth_gate.dart para adicionar widgets sideBuilder.
auth_gate.dart (link em inglês)
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();
},
);
}
}
O app vai ficar assim quando você expandir a largura da janela (se estiver usando o Flutter na Web ou MacOS).
Criar um usuário
Neste ponto, todo o código da tela está concluído. Antes de fazer login, porém, é necessário criar um usuário. Você pode fazer isso na tela "Registrar" ou criar um usuário no console do Firebase.
Para usar o console:
- Acesse a tabela "Usuários" no Console do Firebase.
- Clique aqui
- Selecione "flutterfire-ui-codelab" ou outro projeto caso você tenha usado um nome diferente. Você vai encontrar esta tabela:
- Clique no botão "Adicionar usuário".
- Digite um endereço de e-mail e uma senha para o novo usuário. Pode ser um e-mail e uma senha falsos, como eu digitei na imagem abaixo. Isso vai funcionar, mas a funcionalidade "Esqueci a senha" não vai funcionar se você usar um endereço de e-mail falso.
- Clique em "Adicionar usuário"
Agora, você pode retornar ao aplicativo do Flutter e fazer o login de um usuário na página de login. O app vai ficar assim:
6. Tela do perfil
A interface do FlutterFire também oferece um widget ProfileScreen
, que oferece muitas funcionalidades com apenas algumas linhas de código.
Adicionar widget ProfileScreen
Navegue até o arquivo home.dart
no seu editor de texto. Atualize com este código:
home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => const ProfileScreen(),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
O novo código de observação é o callback transmitido para o IconButton.isPressed method.
. Quando esse IconButton
é pressionado, o aplicativo cria uma nova rota anônima e navega até ela. Essa rota exibirá o widget ProfileScreen
, que é retornado do callback MaterialPageRoute.builder
.
Atualize o aplicativo e pressione o ícone no canto superior direito (na barra de aplicativos). Ele exibirá uma página como esta:
Essa é a interface padrão fornecida pela página de interface do FlutterFire. Todos os botões e campos de texto são conectados ao Firebase Auth e funcionam imediatamente. Por exemplo, se você inserir um nome no campo de texto "Nome", a interface do FlutterFire chamará o método FirebaseAuth.instance.currentUser?.updateDisplayName
, que salvará esse nome no Firebase.
Saindo
Por enquanto, se você pressionar o botão "Sair", o aplicativo não mudará. Você será desconectado, mas não será levado de volta ao widget AuthGate. Para implementar isso, use o parâmetro ProfileScreen.actions.
Primeiro, atualize o código em home.dart.
home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
})
],
),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
Agora, ao criar uma instância de ProfileScreen
, você também transmite uma lista de ações para o argumento ProfileScreen.actions
. Essas ações são do tipo FlutterFireUiAction
. Há muitas classes diferentes que são subtipos de FlutterFireUiAction
e, em geral, elas são usadas para instruir o app a reagir a diferentes mudanças de estado de autenticação. O SignedOutAction chama uma função de callback que é fornecida quando o estado de autenticação do Firebase muda para o currentUser sendo nulo.
Ao adicionar um callback que chama Navigator.of(context).pop()
quando SignedOutAction é acionado, o app vai navegar para a página anterior. Neste app de exemplo, há apenas uma rota permanente, que mostra a página de login se não houver um usuário conectado, e a página inicial, se houver. Como isso acontece quando o usuário sai, o aplicativo exibe a página de login.
Personalizar a página de perfil
Assim como a página de login, a página do perfil é personalizável. Primeiro, nossa página atual não tem como voltar à página inicial quando um usuário está na página de perfil. Para corrigir isso, atribua uma AppBar ao widget ProfileScreen.
home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
appBar: AppBar(
title: const Text('User Profile'),
),
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
})
],
),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
O argumento ProfileScreen.appBar
aceita um widget AppBar
do pacote Flutter Material para que possa ser tratado como qualquer outro AppBar
que você tenha criado e transmitido para um Scaffold
. Nesse exemplo, a funcionalidade padrão de adicionar automaticamente um botão "Voltar" é mantida, e a tela agora tem um título.
Adicionar filhos à tela do perfil
O widget ProfileScreen também tem um argumento opcional chamado "filhos". Esse argumento aceita uma lista de widgets, que serão colocados verticalmente dentro de um widget Column que já é usado internamente para criar a ProfileScreen. Esse widget Column no método de compilação ProfileScreen colocará os filhos que você transmitir acima do botão "Sign out".
Atualize o código em home.dart para mostrar o logotipo da empresa aqui, semelhante à tela de login.
home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
appBar: AppBar(
title: const Text('User Profile'),
),
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
})
],
children: [
const Divider(),
Padding(
padding: const EdgeInsets.all(2),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
),
],
),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
Atualize o app e você verá o seguinte na tela:
7. Login do Google Auth multiplataforma
A interface do FlutterFire também oferece widgets e funcionalidades para autenticação com provedores externos, como Google, Twitter, Facebook, Apple e GitHub.
Para integrar com a autenticação do Google, instale o plug-in firebase_ui_oauth_google oficial e as dependências dele que manipularão o fluxo de autenticação nativo. No terminal, navegue até a raiz do seu projeto do Flutter e digite o seguinte comando:
flutter pub add google_sign_in flutter pub add firebase_ui_oauth_google
Ativar o provedor de login do Google
Em seguida, ative o provedor Google no Console do Firebase:
- Navegue até a tela Provedores de login de autenticação no console.
- Clique em "Adicionar novo provedor".
- Selecione "Google".
- Selecione a chave "Ativar" e pressione "Salvar".
- Se um modal aparecer com informações sobre como fazer o download dos arquivos de configuração, clique em "Concluído".
- Confirme se o provedor de login do Google foi adicionado.
Adicionar o botão de Login do Google
Com o Login do Google ativado, adicione o widget necessário para exibir um botão de login estilizado do Google na página de login. Navegue até o arquivo auth_gate.dart e atualize o código para o seguinte:
auth_gate.dart (link em inglês)
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();
},
);
}
}
O único código novo aqui é a adição de GoogleProvider(clientId: "YOUR_WEBCLIENT_ID")
à configuração do widget SignInScreen.
Com isso adicionado, atualize o app para ver o botão de Login do Google.
Configurar botão de login
O botão não funciona sem outras configurações. Se estiver desenvolvendo com o Flutter Web, esta é a única etapa que você precisa adicionar para que o recurso funcione. Outras plataformas exigem etapas adicionais, que serão abordadas mais adiante.
- Acesse a página "Provedores do Authentication" no Console do Firebase.
- Clique no provedor do Google.
- Clique no painel de expansão "Configuração do SDK da Web".
- Copie o valor de "ID do cliente da Web"
- Volte ao editor de texto e atualize a instância de
GoogleProvider
no arquivoauth_gate.dart
transmitindo esse ID para o parâmetro chamadoclientId
.
GoogleProvider(
clientId: "YOUR_WEBCLIENT_ID"
)
Depois de inserir o ID do cliente da Web, recarregue o app. Ao pressionar o botão "Fazer login com o Google", uma nova janela vai aparecer (se você estiver usando a Web), que vai guiar você pelo fluxo de login do Google. Inicialmente, ela tem esta aparência:
Configurar o iOS
Para que isso funcione no iOS, há um processo de configuração adicional.
- Navegue até a tela "Configurações do projeto" no Console do Firebase. Haverá um card que lista seus apps do Firebase com a seguinte aparência:
- Clique no iOS. O nome do seu aplicativo será diferente do meu. Quando o meu estiver concluído, o seu dirá "iniciar", se você tiver usado o projeto
flutter-codelabs/firebase-auth-flutterfire-ui/start
para acompanhar este codelab. - Clique no botão "GoogleServices-Info.plist" para fazer o download do arquivo de configuração necessário.
- Arraste e solte o arquivo baixado no diretório .
/ios/Runner
no seu projeto do Flutter. - Abra o Xcode executando o seguinte comando do terminal na raiz do seu projeto:
abrir ios/Runner.xcworkspace
- Clique com o botão direito do mouse no diretório "Runner" e selecione "Adicionar arquivos a "Runner".
- Selecione GoogleService-Info.plist no gerenciador de arquivos.
- No editor de texto que não é o Xcode, adicione os atributos CFBundleURLTypes abaixo ao arquivo [my_project]/ios/Runner/Info.plist.
<!-- Put me in the [my_project]/ios/Runner/Info.plist file -->
<!-- Google Sign-in Section -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- TODO Replace this value: -->
<!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID -->
<string>com.googleusercontent.apps.861823949799-vc35cprkp249096uujjn0vvnmcvjppkn</string>
</array>
</dict>
</array>
<!-- End of the Google Sign-in Section -->
Se o app do Flutter já estiver em execução no iOS, será necessário desativá-lo completamente e executá-lo novamente. Caso contrário, execute o app no iOS.
8. Parabéns!
Você concluiu o codelab da interface do Firebase Auth para Flutter . O código completo deste codelab está disponível no diretório "completo" do GitHub: Flutter Codelabs (link em inglês).
O que aprendemos
- Como configurar um app do Flutter para usar o Firebase
- Como configurar um projeto do Firebase no Console do Firebase
- CLI do FlutterFire
- CLI do Firebase
- Como usar o Firebase Authentication
- Usar a interface do FlutterFire para processar facilmente a autenticação do Firebase no seu app do Flutter
Próximas etapas
- Saiba mais sobre como usar o Firestore e a autenticação no Flutter: Codelab do Firebase para Flutter
- Explore outras ferramentas do Firebase para criar seu aplicativo do Flutter:
- Cloud Storage
- Cloud Functions
- Realtime Database
Saiba mais
- Site do Firebase: firebase.google.com
- Site do Flutter: flutter.dev
- Widgets Flutter do Firebase para Flutter: firebase.flutter.dev
- Canal do Firebase no YouTube
- Canal do Flutter no YouTube
O Sparky está aqui para comemorar com você!