1. Antes de começar
Neste codelab, você aprenderá como adicionar o Firebase Authentication ao seu aplicativo Flutter usando o pacote de IU do FlutterFire. Com este pacote, você adicionará autenticação de e-mail/senha e autenticação de login do Google a um aplicativo Flutter. Você também aprenderá como configurar um projeto do Firebase e usar a CLI do FlutterFire para inicializar o Firebase em seu aplicativo Flutter.
Pré-requisitos
Este codelab pressupõe que você tenha alguma experiência com Flutter. Caso contrário, você pode querer primeiro aprender o básico. Os seguintes links são úteis:
- Faça um tour pela estrutura do Flutter Widget
- Experimente o codelab Escreva seu primeiro aplicativo Flutter, parte 1
Você também deve ter alguma experiência com Firebase, mas está tudo bem se você nunca adicionou o Firebase a um projeto Flutter. Se você não está familiarizado com o console do Firebase ou é completamente novo no Firebase, consulte primeiro os seguintes links:
O que você criará
Este codelab orienta você na criação do fluxo de autenticação para um aplicativo Flutter usando o Firebase for Authentication. O aplicativo terá uma tela de login, uma tela de ‘Cadastro’, uma tela de recuperação de senha e uma tela de perfil de usuário.
O que você aprenderá
Este codelab abrange:
- Adicionando Firebase a um aplicativo Flutter
- Configuração do Console do Firebase
- Usando Firebase CLI para adicionar Firebase ao seu aplicativo
- Usando FlutterFire CLI para gerar configuração do Firebase no Dart
- Adicionando Firebase Authentication ao seu aplicativo Flutter
- Configuração do Firebase Authentication no console
- Adicionando login de e-mail e senha com o pacote
firebase_ui_auth
- Adicionando registro de usuário com o pacote
firebase_ui_auth
- Adicionando uma mensagem 'Esqueceu a senha?' página
- Adicionando login do Google com
firebase_ui_auth
- Configurando seu aplicativo para funcionar com vários provedores de login.
- Adicionando uma tela de perfil de usuário ao seu aplicativo com o pacote
firebase_ui_auth
Este codelab se preocupa especificamente em adicionar um sistema de autenticação robusto usando o pacote firebase_ui_auth
. Como você verá, todo esse aplicativo, com todos os recursos acima, pode ser implementado com cerca de 100 linhas de código.
O que você precisará
- Conhecimento prático de Flutter e do SDK instalado
- Um editor de texto (JetBrains IDE, Android Studio e VS Code são suportados pelo Flutter)
- Navegador Google Chrome ou outro alvo de desenvolvimento preferido para Flutter. (Alguns comandos de terminal neste codelab presumirão que você está executando seu app no Chrome)
2. Crie e configure um projeto Firebase
A primeira tarefa que você precisará concluir é criar um projeto do Firebase no console da web do Firebase.
Crie um projeto do Firebase
- Faça login no Firebase .
- No console do Firebase, clique em Adicionar projeto (ou Criar um projeto ) e insira um nome para seu projeto do Firebase (por exemplo, " FlutterFire-UI-Codelab ").
- Clique nas opções de criação do projeto. Aceite os termos do Firebase, se solicitado. Ignore a configuração do Google Analytics porque você não usará o Analytics para este aplicativo.
Para saber mais sobre os projetos do Firebase, consulte Entender os projetos do Firebase .
O aplicativo que você está criando usa o Firebase Authentication para permitir que os usuários façam login no aplicativo. Também permite que novos usuários se registrem no aplicativo Flutter.
O Firebase Authentication precisa ser ativado usando o Firebase Console e precisa de configuração especial depois de ativado.
Ativar login por e-mail para Firebase Authentication
Para permitir que os usuários façam login no aplicativo Web, primeiro você usará o método de login por e-mail/senha . Posteriormente, você 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, clique no botão Começar e, em seguida, na guia Método de login (ou clique aqui para ir diretamente para a guia Método de login ).
- Clique em E-mail/Senha na lista Provedores de login , defina o botão Ativar para a posição ativado e clique em Salvar .
3. Configure o aplicativo Flutter
Você precisará baixar o código inicial e instalar a CLI do Firebase antes de começarmos.
Obtenha o código inicial
Clone o repositório GitHub na 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 código de amostra deve ser clonado no diretório flutter-codelabs
da sua 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 Flutter. Um é chamado de complete
e o outro é chamado de start
. O diretório start
contém um projeto incompleto e é onde você 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 concluído, procure no diretório chamado complete para referência cruzada.
Se quiser acompanhar o codelab e adicionar código você mesmo, comece com o aplicativo Flutter em flutter-codelabs/firebase-auth-flutterfire-ui/start
e adicione código a esse projeto durante todo o codelab. Abra ou importe esse diretório para o seu IDE preferido.
Instale a CLI do Firebase
A Firebase CLI fornece ferramentas para gerenciar seus projetos do Firebase. A CLI é necessária para a CLI do FlutterFire, que você instalará em breve.
Existem várias maneiras de instalar a CLI. A maneira mais simples, se você estiver usando MacOS ou Linux, é executar este comando em seu terminal:
curl -sL https://firebase.tools | bash
Depois de instalar a CLI, você deve se autenticar no Firebase.
- Faça login no Firebase usando sua conta do Google executando o seguinte comando:
firebase login
- Este comando conecta sua máquina local ao Firebase e concede acesso aos seus projetos do Firebase.
- Teste se a CLI está instalada corretamente e tem acesso à sua conta listando seus projetos do Firebase. Execute o seguinte comando:
firebase projects:list
- A lista exibida deve ser a mesma dos projetos do Firebase listados no console do Firebase . Você deve ver pelo menos
flutterfire-ui-codelab.
Instale a CLI do FlutterFire
A CLI do FlutterFire é uma ferramenta que ajuda a facilitar o processo de instalação do Firebase em todas as plataformas suportadas em seu aplicativo Flutter. Ele foi desenvolvido com base na CLI do Firebase.
Primeiro, instale a CLI:
dart pub global activate flutterfire_cli
Certifique-se de que a CLI esteja instalada. Execute o comando a seguir e certifique-se de que a CLI gere o menu de ajuda.
flutterfire -—help
Adicione seu projeto do Firebase ao seu aplicativo Flutter
Configurar FlutterFire
Você pode usar o FlutterFire para gerar o código Dart necessário para usar o Firebase em seu aplicativo Flutter.
flutterfire configure
Quando este comando for executado, você será solicitado a selecionar qual projeto do Firebase deseja usar e quais plataformas deseja configurar.
As capturas de tela a seguir mostram os prompts que você precisará responder.
- Selecione o projeto que deseja usar. Neste caso, use
flutterfire-ui-codelab
- Selecione quais plataformas você deseja usar. Neste codelab, há etapas para configurar o Firebase Authentication for Flutter para 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 você estiver familiarizado com o Firebase, notará que não foi necessário criar aplicativos de plataforma (por exemplo, um aplicativo Android) no console, e a CLI do FlutterFire fez isso por você.
Quando isso estiver concluído, consulte o aplicativo Flutter em seu editor de texto. A CLI do FlutterFire gerou um novo arquivo chamado firebase_options.dart
. Este arquivo contém uma classe chamada FirebaseOptions, que possui variáveis estáticas que contêm a configuração do Firebase necessária para cada plataforma. Se você selecionou todas as plataformas ao executar flutterfire configure
, verá valores estáticos chamados web
, android
, ios
e macos
.
firebase_options.dart
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
// ignore: missing_enum_constant_in_switch
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
}
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyCqFjCV_9CZmYeIvcK9FVy4drmKUlSaIWY',
appId: '1:963656261848:web:7219f7fca5fc70afb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
authDomain: 'flutterfire-ui-codelab.firebaseapp.com',
storageBucket: 'flutterfire-ui-codelab.appspot.com',
measurementId: 'G-DGF0CP099H',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyDconZaCQpkxIJ5KQBF-3tEU0rxYsLkIe8',
appId: '1:963656261848:android:c939ccc86ab2dcdbb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.appspot.com',
iosClientId: '963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com',
iosBundleId: 'com.example.complete',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.appspot.com',
iosClientId: '963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com',
iosBundleId: 'com.example.complete',
);
}
O Firebase usa a palavra aplicativo para se referir a uma compilação específica para uma plataforma específica em um projeto do Firebase. Por exemplo, o projeto Firebase chamado FlutterFire-ui-codelab possui vários aplicativos: um para Android, um para iOS, um para MacOS e um para Web.
O método DefaultFirebaseOptions.currentPlatform
usa o enum TargetPlatform
exposto pelo Flutter para detectar a plataforma em que seu aplicativo está sendo executado e, em seguida, retorna os valores de configuração do Firebase necessários para o aplicativo Firebase correto.
Adicionar pacotes do Firebase ao aplicativo Flutter
A etapa final de configuração é adicionar os pacotes Firebase relevantes ao seu projeto Flutter. O arquivo firebase_options.dart
deve conter erros, pois 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
Estes são os únicos pacotes que você precisa neste momento.
Inicializar Firebase
Para utilizar os pacotes adicionados e o DefaultFirebaseOptions.currentPlatform,
atualize o código na função main
no arquivo main.dart
.
principal.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}
Este código faz duas coisas.
-
WidgetsFlutterBinding.ensureInitialized()
diz ao Flutter para não começar a executar o código do widget do aplicativo até que a estrutura do Flutter seja completamente inicializada. O Firebase usa canais de plataforma nativos, que exigem que o framework esteja em execução. -
Firebase.initializeApp
configura uma conexão entre seu aplicativo Flutter e seu projeto Firebase. ODefaultFirebaseOptions.currentPlatform
é importado de nosso arquivofirebase_options.dart
gerado. Esse valor estático detecta em qual plataforma você está executando e transmite as chaves correspondentes do Firebase.
4. Adicione a página inicial do Firebase UI Auth
O Firebase UI for Auth fornece widgets que representam telas inteiras do seu aplicativo. Essas telas lidam com diferentes fluxos de autenticação em todo o seu aplicativo, como Login, Registro, Esqueci a senha, Perfil do usuário e muito mais. Para começar, adicione uma landing page ao seu aplicativo que atue como uma proteção de autenticação para o aplicativo principal.
Material ou aplicativo Cupertino
A UI do FlutterFire requer que seu aplicativo seja empacotado em um MaterialApp ou CupertinoApp. Dependendo da sua escolha, a IU refletirá automaticamente as diferenças dos widgets Material ou Cupertino. Neste codelab, use MaterialApp
, que já foi adicionado ao aplicativo em app.dart
.
aplicativo.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(),
);
}
}
Verifique o estado de autenticação
Antes de poder exibir uma tela de login, você precisa determinar se o usuário está autenticado no momento. A maneira mais comum de verificar isso é ouvir authStateChanges do FirebaseAuth usando o plug-in Firebase Auth .
No exemplo de código acima, o MaterialApp
está construindo um widget AuthGate
em seu método de construção. (Este é um widget personalizado, não fornecido pela UI 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 estiver conectado) ou nulo se não estiver. Para assinar esse estado em nosso aplicativo, você pode usar o widget StreamBuilder do Flutter e passar o stream para ele.
StreamBuilder
é um widget que se constrói com base no instantâneo mais recente de dados de um Stream que você passa. Ele reconstrói automaticamente quando o Stream emite um novo instantâneo.
Atualize o código em auth_gate.dart
.
auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [],
);
}
return const HomeScreen();
},
);
}
}
-
StreamBuilder.stream
está sendo passadoFirebaseAuth.instance.authStateChanged
, o stream mencionado acima, que retornará um objeto FirebaseUser
se o usuário tiver se autenticado. (Caso contrário, retornaránull
.) - A seguir, o código usa
snapshot.hasData
para verificar se o valor do fluxo contém o objetoUser
. - Se não houver, retornará um widget
SignInScreen
. Atualmente, essa tela não fará nada. Isso será atualizado na próxima etapa. - Caso contrário, ele retorna um
HomeScreen
, que é a parte principal da aplicação que somente usuários autenticados podem acessar.
O SignInScreen
é um widget que vem do pacote FlutterFire UI. Esse será o foco da próxima etapa deste codelab. Ao executar o aplicativo neste ponto, você verá uma tela de login em branco.
5. Tela de login
O widget SignInScreen
, fornecido pela UI FlutterFire, adiciona a seguinte funcionalidade:
- Permite que os usuários façam login
- Se os usuários esquecerem a senha, poderão tocar em "Esqueceu a senha?" e será levado a um formulário para redefinir sua senha
- Se um usuário ainda não estiver cadastrado, ele pode tocar em “Cadastre-se” e ser direcionado para outro formulário que permite a inscrição.
Novamente, isso requer apenas algumas linhas de código. Lembre-se do código no 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();
},
);
}
}
O widget SignInScreen
e seu argumento providers
são o único código necessário para obter todas as funcionalidades mencionadas acima. Agora você deve ver uma tela de login com entradas de texto 'e-mail' e 'senha', bem como um botão 'Entrar'.
Embora funcional, falta estilo. O widget expõe parâmetros para personalizar a aparência da tela de login. Por exemplo, você pode querer adicionar o logotipo da sua empresa.
Personalize a tela de login
construtor de cabeçalho
Usando o argumento SignInScreen.headerBuilder
, você pode adicionar quaisquer widgets que desejar acima do formulário de login. Atualize o arquivo auth_gate.dart
com 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();
},
);
}
}
O argumento headerBuilder requer uma função do tipo HeaderBuilder, que é definida no pacote de UI do FlutterFire.
typedef HeaderBuilder = Widget Function(
BuildContext context,
BoxConstraints constraints,
double shrinkOffset,
);
Por ser um retorno de chamada, ele expõe valores que você pode usar, como BuildContext
e BoxConstraints
e exige que você retorne um widget. Qualquer widget que você retornar será exibido na parte superior da tela. Neste exemplo, o novo código adiciona uma imagem ao topo da tela. Seu aplicativo agora deve ficar assim.
Construtor de legendas
A tela de login expõe três parâmetros adicionais que permitem personalizar a tela: subtitleBuilder
, footerBuilder
e sideBuilder
.
O subtitleBuilder
é um pouco diferente porque os argumentos de retorno de chamada incluem uma ação, que é do tipo AuthAction
. AuthAction
é uma enumeração que você pode usar para detectar se a tela em que o usuário está é a tela de "login" ou a tela de "registro".
Atualize o código em auth_gate.dart para usar o 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();
},
);
}
}
Recarregue o aplicativo e ele deverá ficar assim
Construtor de rodapé
O argumento footerBuilder é igual ao subtitleBuilder. Ele não expõe BoxConstraints
ou shrinkOffset
, pois se destina a texto e não a imagens. (Embora você possa adicionar qualquer widget que desejar.)
Adicione um rodapé à sua tela de login com 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();
},
);
}}
Construtor lateral
O argumento SignInScreen.sidebuilder aceita um retorno de chamada e, desta vez, os argumentos para esse retorno de chamada são BuildContext
e double shrinkOffset
. O widget retornado pelo sideBuilder será exibido à esquerda do formulário de login e apenas em telas amplas. Efetivamente, isso significa que o widget só será exibido em aplicativos de desktop e da web.
Internamente, a UI do FlutterFire usa um ponto de interrupção para determinar se o conteúdo do cabeçalho deve ser mostrado (em telas altas, como dispositivos móveis) ou o conteúdo lateral deve ser mostrado (em telas largas, desktop ou web). Especificamente, se uma tela tiver mais de 800 pixels de largura, o conteúdo do construtor lateral será mostrado e o conteúdo do cabeçalho não. Se a tela tiver menos de 800 pixels de largura, o oposto é verdadeiro.
Atualize o código em auth_gate.dart para adicionar 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();
},
);
}
}
Seu aplicativo agora deve ficar assim quando você expande a largura da janela (se você estiver usando Flutter web ou MacOS).
Crie um usuário
Neste ponto, todo o código desta tela está concluído. Antes de fazer login, porém, você precisa criar um usuário. Você pode fazer isso na tela "Registrar" ou pode criar um usuário no console do Firebase.
Para usar o console:
- Vá para a tabela “Usuários” no console do Firebase.
- Clique aqui
- Selecione 'flutterfire-ui-codelab' (ou outro projeto se você usou um nome diferente). Você verá esta tabela:
- Clique no botão "Adicionar usuário".
- Digite um endereço de e-mail e senha para o novo usuário. Pode ser um e-mail e uma senha falsos, conforme digitei na imagem abaixo. Isso funcionará, mas a funcionalidade “Esqueci a senha” não funcionará se você usar um endereço de e-mail falso.
- Clique em "Adicionar usuário"
Agora, você pode retornar ao seu aplicativo Flutter e fazer login de um usuário por meio da página de login. Seu aplicativo deve ficar assim:
6. Tela de perfil
A UI do FlutterFire também fornece um widget ProfileScreen
, que, novamente, oferece muitas funcionalidades em algumas linhas de código.
Adicionar widget ProfileScreen
Navegue até o arquivo home.dart
em seu editor de texto. Atualize-o 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 digno de nota é o retorno de chamada passado para o IconButton.isPressed method.
Quando esse IconButton
é pressionado, seu aplicativo cria uma nova rota anônima e navega até ela. Essa rota exibirá o widget ProfileScreen
, que é retornado do retorno de chamada MaterialPageRoute.builder
.
Recarregue seu aplicativo e pressione o ícone no canto superior direito (na barra de aplicativos) e uma página como esta será exibida:
Esta é a UI padrão fornecida pela página UI do FlutterFire. Todos os botões e campos de texto estão conectados ao Firebase Auth e funcionam imediatamente. Por exemplo, você pode inserir um nome no campo de texto "Nome" e a UI do FlutterFire chamará o método FirebaseAuth.instance.currentUser?.updateDisplayName
, que salvará esse nome no Firebase.
Saindo
No momento, se você pressionar o botão “Sair”, o aplicativo não será alterado. Ele desconectará você, mas você não será direcionado 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 passa uma lista de ações para o argumento ProfileScreen.actions
. Essas ações são do tipo FlutterFireUiAction
. Existem muitas classes diferentes que são subtipos de FlutterFireUiAction
e, em geral, você as usa para instruir seu aplicativo a reagir a diferentes alterações de estado de autenticação. O SignedOutAction chama uma função de retorno de chamada que você fornece quando o estado de autenticação do Firebase muda para currentUser sendo nulo.
Ao adicionar um retorno de chamada que chama Navigator.of(context).pop()
quando SignedOutAction é acionado, o aplicativo navegará para a página anterior. Neste aplicativo 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 um usuário. Como isso acontece quando o usuário sai, o aplicativo exibirá a página SignIn.
Personalize a página de perfil
Semelhante à página de login, a página de perfil é personalizável. Primeiro, nossa página atual não tem como voltar à página inicial quando o usuário está na página de perfil. Corrija isso fornecendo ao widget ProfileScreen um AppBar.
home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
appBar: AppBar(
title: const Text('User Profile'),
),
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
})
],
),
),
);
},
)
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
Image.asset('dash.png'),
Text(
'Welcome!',
style: Theme.of(context).textTheme.displaySmall,
),
const SignOutButton(),
],
),
),
);
}
}
O argumento ProfileScreen.appBar
aceita um widget AppBar
do pacote Flutter Material, portanto, pode ser tratado como qualquer outro AppBar
que você construiu e passou para um Scaffold
. Neste exemplo, a funcionalidade padrão de adicionar automaticamente um botão “voltar” é mantida e a tela agora possui um título.
Adicionar crianças à tela de perfil
O widget ProfileScreen também possui um argumento opcional denominado filhos. Este argumento aceita uma lista de widgets, e esses widgets serão colocados verticalmente dentro de um widget Column que já foi usado internamente para construir o ProfileScreen. Este widget Coluna no método de construção ProfileScreen colocará os filhos que você passar acima do botão "Sair".
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(),
],
),
),
);
}
}
Recarregue seu aplicativo e você verá isto na tela:
7. Login de autenticação do Google multiplataforma
A UI do FlutterFire também fornece widgets e funcionalidades para autenticação com provedores terceirizados, como Google, Twitter, Facebook, Apple e Github.
Para integrar com a autenticação do Google, instale o plugin oficial firebase_ui_oauth_google e suas dependências, que irão lidar com o fluxo de autenticação nativa. No terminal, navegue até a raiz do seu projeto flutter e digite o seguinte comando:
flutter pub add google_sign_in flutter pub add firebase_ui_oauth_google
Ativar provedor de login do Google
Em seguida, habilite o provedor Google no Firebase Console :
- Navegue até a tela Provedores de login de autenticação no console.
- Clique em "Adicionar novo provedor".
- Selecione "Google".
- Alterne a chave rotulada como "Ativar" e pressione "Salvar".
- Caso apareça um modal com informações sobre o download dos arquivos de configuração, clique em “Concluído”.
- Confirme se o provedor de login do Google foi adicionado.
Adicionar botão de login do Google
Com o login do Google ativado, adicione o widget necessário para exibir um botão estilizado de login 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
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, recarregue seu aplicativo e você verá um botão de login do Google.
Configurar botão de login
O botão não funciona sem configuração adicional. Se você estiver desenvolvendo com Flutter Web, esta é a única etapa que você precisa adicionar para que funcione. Outras plataformas requerem etapas adicionais, que serão discutidas em breve.
- Navegue até a página Provedores de autenticação no Firebase Console .
- Clique no provedor do Google.
- Clique no painel de expansão "Configuração do Web SDK".
- Copie o valor de 'ID do cliente Web"
- Retorne ao seu editor de texto e atualize a instância do
GoogleProvider
no arquivoauth_gate.dart
passando esse ID para o parâmetro nomeadoclientId
.
GoogleProvider(
clientId: "YOUR_WEBCLIENT_ID"
)
Depois que o ID do cliente web for inserido, recarregue seu aplicativo. Ao pressionar o botão "Fazer login com o Google", uma nova janela aparecerá (se você estiver usando a web) que o guiará pelo fluxo de login do Google. Inicialmente, fica assim:
Configurar iOS
Para que isso funcione no iOS, existe um processo de configuração adicional.
- Navegue até a tela Configurações do projeto no console do Firebase . Haverá um cartão que lista seus aplicativos do Firebase parecido com este:
- Clique no iOS. Observe que o nome do seu aplicativo será diferente do meu. Onde o meu diz "completo", o seu dirá "iniciar", se você usou o projeto
flutter-codelabs/firebase-auth-flutterfire-ui/start
para acompanhar este codelab. - Clique no botão que diz “GoogleServices-Info.plist” para baixar o arquivo de configuração necessário.
- Arraste e solte o arquivo baixado no diretório chamado .
/ios/Runner
em seu projeto Flutter. - Abra o Xcode executando o seguinte comando de terminal na raiz do seu projeto:
abra ios/Runner.xcworkspace
- Clique com o botão direito no diretório Runner e selecione Adicionar arquivos ao "Runner".
- Selecione GoogleService-Info.plist no gerenciador de arquivos.
- De volta ao seu 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 seu aplicativo Flutter já estiver em execução no iOS, você deverá desligá-lo completamente e executar o aplicativo novamente. Caso contrário, execute o aplicativo no iOS.
8. Parabéns!
Você concluiu o codelab Firebase Auth UI para Flutter. Você pode encontrar o código completo deste Codelab no diretório "complete" no github: Flutter Codelabs
O que cobrimos
- Configurando um aplicativo Flutter para usar o Firebase
- Configurando um projeto do Firebase no console do Firebase
- CLI do FlutterFire
- CLI do Firebase
- Usando a autenticação Firebase
- Usando a UI do FlutterFire para lidar facilmente com a autenticação do Firebase em seu aplicativo Flutter
Próximos passos
- Saiba mais sobre como usar o Firestore e o Authentication no Flutter: Conheça o Firebase para Flutter Codelab
- Explore outras ferramentas do Firebase para criar seu aplicativo Flutter:
- Armazenamento na núvem
- Funções de nuvem
- Banco de dados em tempo real
Saber mais
- Site do Firebase: firebase.google.com
- Site de vibração: flutter.dev
- Widgets FlutterFire Firebase Flutter: firebase.flutter.dev
- Canal do Firebase no YouTube
- Canal Flutter no YouTube
Sparky está aqui para comemorar com você!