Desenvolvimento local para seus aplicativos Flutter usando o Firebase Emulator Suite

1. Antes de começar

Neste codelab, você aprenderá a usar o Firebase Emulator Suite com Flutter durante o desenvolvimento local. Você aprenderá como usar a autenticação de senha de e-mail por meio do Emulator Suite e como ler e gravar dados no emulador do Firestore. Por fim, você trabalhará com importação e exportação de dados dos emuladores, para trabalhar com os mesmos dados falsificados sempre que retornar ao desenvolvimento.

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:

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 de um aplicativo simples de registro no diário. O aplicativo terá uma tela de login e uma tela que permite ler lançamentos anteriores e criar novos.

cd5c4753bbee8af.png8cb4d21f656540bf.png

O que você aprenderá

Você aprenderá como começar a usar o Firebase e como integrar e usar o pacote Firebase Emulator em seu fluxo de trabalho de desenvolvimento do Flutter. Estes tópicos do Firebase serão abordados:

Observe que esses tópicos são abordados na medida em que são necessários para cobrir o pacote de emuladores do Firebase. Este codelab se concentra na adição de um projeto do Firebase ao seu aplicativo Flutter e no desenvolvimento usando o Firebase Emulator Suite. Não haverá discussões aprofundadas sobre Firebase Authentication ou Firestore. Se você não estiver familiarizado com esses tópicos, recomendamos começar com o codelab Conhecendo o Firebase for Flutter .

O que você precisará

  • Conhecimento prático de Flutter e do SDK instalado
  • Editores de texto Intellij JetBrains ou VS Code
  • Navegador Google Chrome (ou outro destino de desenvolvimento preferido para Flutter. Alguns comandos de terminal neste codelab presumirão que você está executando seu aplicativo 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. A grande maioria deste codelab se concentrará no Emulator Suite, que usa uma IU executada localmente, mas primeiro você precisa configurar um projeto completo do Firebase.

Crie um projeto do Firebase

  1. Faça login no console do Firebase.
  2. No console do Firebase, clique em Adicionar projeto (ou Criar um projeto ) e insira um nome para seu projeto do Firebase (por exemplo, " Firebase-Flutter-Codelab") .

fe6aeab3b91965ed.png

  1. 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.

d1fcec48bf251eaa.png

Para saber mais sobre os projetos do Firebase, consulte Entender os projetos do Firebase .

O aplicativo que você está criando usa dois produtos do Firebase disponíveis para aplicativos Flutter:

  • Firebase Authentication para permitir que seus usuários façam login em seu aplicativo.
  • Cloud Firestore para salvar dados estruturados na nuvem e receber notificações instantâneas quando os dados forem alterados.

Esses dois produtos precisam de configuração especial ou precisam ser habilitados usando o console do Firebase.

Ativar o Cloud Firestore

O aplicativo Flutter usa o Cloud Firestore para salvar lançamentos contábeis manuais.

Ative o Cloud Firestore:

  1. Na seção Build do console do Firebase, clique em Cloud Firestore .
  2. Clique em Criar banco de dados . 99e8429832d23fa3.png
  3. Selecione a opção Iniciar em modo de teste . Leia o aviso sobre as regras de segurança. O modo de teste garante que você possa gravar livremente no banco de dados durante o desenvolvimento. Clique em Avançar . 6be00e26c72ea032.png
  4. Selecione o local do seu banco de dados (você pode usar apenas o padrão). Observe que este local não pode ser alterado posteriormente. 278656eefcfb0216.png
  5. Clique em Habilitar .

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 , que contém o código de uma coleção de codelabs. O código deste codelab está em flutter-codelabs/firebase-emulator-suite .

A estrutura de diretórios em flutter-codelabs/firebase-emulator-suite é composta por dois projetos Flutter. Um é chamado complete , ao qual você pode consultar se quiser avançar ou fazer referência cruzada ao seu próprio código. O outro projeto é chamado start .

O código com o qual você deseja começar está no diretório flutter-codelabs/firebase-emulator-suite/start . Abra ou importe esse diretório para o seu IDE preferido.

cd flutter-codelabs/firebase-emulator-suite/start

Instale a CLI do Firebase

A Firebase CLI fornece ferramentas para gerenciar seus projetos do Firebase. A CLI é necessária para usar o Emulator Suite, portanto você precisará instalá-la.

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.

  1. Faça login no Firebase usando sua conta do Google executando o seguinte comando:
firebase login
  1. Este comando conecta sua máquina local ao Firebase e concede acesso aos seus projetos do Firebase.
  1. Teste se a CLI está instalada corretamente e tem acesso à sua conta listando seus projetos do Firebase. Execute o seguinte comando:
firebase projects:list
  1. A lista exibida deve ser a mesma dos projetos do Firebase listados no console do Firebase . Você deve ver pelo menos firebase-flutter-codelab.

Instale a CLI do FlutterFire

A CLI do FlutterFire é construída com base na CLI do Firebase e facilita a integração de um projeto do Firebase com seu aplicativo Flutter.

Primeiro, instale a CLI:

dart pub global activate flutterfire_cli

Certifique-se de que a CLI esteja instalada. Execute o seguinte comando no diretório do projeto Flutter e certifique-se de que a CLI gere o menu de ajuda.

flutterfire --help

Use Firebase CLI e FlutterFire CLI para adicionar seu projeto Firebase ao seu aplicativo Flutter

Com as duas CLIs instaladas, você pode configurar produtos Firebase individuais (como Firestore), baixar os emuladores e adicionar o Firebase ao seu aplicativo Flutter com apenas alguns comandos de terminal.

Primeiro, conclua a configuração do Firebase executando o seguinte:

firebase init

Este comando o guiará por uma série de perguntas necessárias para configurar seu projeto. Estas capturas de tela mostram o fluxo:

  1. Quando solicitado a selecionar recursos, selecione “Firestore” e “Emuladores”. (Não há opção de autenticação, pois ela não usa configuração modificável nos arquivos do projeto Flutter.) fe6401d769be8f53.png
  2. Em seguida, selecione “Usar um projeto existente”, quando solicitado.

f11dcab439e6ac1e.png

  1. Agora, selecione o projeto que você criou na etapa anterior: flutter-firebase-codelab.

3bdc0c6934991c25.png

  1. A seguir, serão feitas uma série de perguntas sobre como nomear os arquivos que serão gerados. Sugiro pressionar “enter” para cada pergunta para selecionar o padrão. 9bfa2d507e199c59.png
  2. Finalmente, você precisará configurar os emuladores. Selecione Firestore e autenticação na lista e pressione “Enter” para cada pergunta sobre as portas específicas a serem usadas para cada emulador. Você deve selecionar o padrão, Sim, quando perguntado se deseja usar a IU do emulador.

No final do processo, você deverá ver uma saída semelhante à captura de tela a seguir.

Importante : sua saída pode ser um pouco diferente da minha, como pode ser visto na imagem abaixo, porque a pergunta final será "Não" por padrão se você já tiver baixado os emuladores.

8544e41037637b07.png

Configurar FlutterFire

Em seguida, 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. Neste codelab, os exemplos usam Flutter Web, mas você pode configurar seu projeto do Firebase para usar todas as opções.

As capturas de tela a seguir mostram os prompts que você precisará responder.

619b7aca6dc15472.png301c9534f594f472.png

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 no console, e a CLI do FlutterFire fez isso por você.

12199a85ade30459.png

Adicionar pacotes do Firebase ao aplicativo Flutter

A etapa final de configuração é adicionar os pacotes Firebase relevantes ao seu projeto Flutter. 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 cloud_firestore

Estes são os únicos pacotes que você usará neste aplicativo.

4. Habilitando emuladores Firebase

Até agora, o aplicativo Flutter e seu projeto Firebase estão configurados para poder usar os emuladores, mas você ainda precisa informar ao código Flutter para redirecionar as solicitações de saída do Firebase para as portas locais.

Primeiro, adicione o código de inicialização do Firebase e o código de configuração do emulador à função main em main.dart.

principal.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

import 'app_state.dart';
import 'firebase_options.dart';
import 'logged_in_view.dart';
import 'logged_out_view.dart';


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

 if (kDebugMode) {
   try {
     FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
     await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
   } catch (e) {
     // ignore: avoid_print
     print(e);
   }
 }

 runApp(MyApp());
}

As primeiras linhas de código inicializam o Firebase. Quase universalmente, se você estiver trabalhando com o Firebase em um aplicativo Flutter, comece chamando WidgetsFlutterBinding.ensureInitialized e Firebase.initializeApp .

Depois disso, o código que começa com a linha if (kDebugMode) informa ao seu aplicativo para direcionar os emuladores em vez de um projeto de produção do Firebase. kDebugMode garante que o direcionamento aos emuladores só acontecerá se você estiver em um ambiente de desenvolvimento. Como kDebugMode é um valor constante, o compilador Dart sabe como remover completamente esse bloco de código no modo de liberação.

Inicie os emuladores

Você deve iniciar os emuladores antes de iniciar o aplicativo Flutter. Primeiro, inicie os emuladores executando isto no terminal:

firebase emulators:start

Este comando inicializa os emuladores e expõe as portas localhost com as quais podemos interagir com eles. Ao executar esse comando, você deverá ver uma saída semelhante a esta:

bb7181eb70829606.png

Esta saída informa quais emuladores estão em execução e onde você pode ir para vê-los. Primeiro, verifique a UI do emulador em localhost:4000 .

11563f4c7216de81.png

Esta é a página inicial da UI do emulador local. Ele lista todos os emuladores disponíveis e cada um é rotulado com status ativado ou desativado.

5. O emulador Firebase Auth

O primeiro emulador que você usará é o emulador de autenticação. Comece com o emulador Auth clicando em "Ir para o emulador" no cartão de autenticação na IU e você verá uma página semelhante a esta:

3c1bfded40733189.png

Esta página tem semelhanças com a página do console web Auth. Possui uma tabela listando os usuários como o console online e permite adicionar usuários manualmente. Uma grande diferença aqui é que a única opção de método de autenticação disponível nos emuladores é via Email e Senha. Isto é suficiente para o desenvolvimento local.

A seguir, você percorrerá o processo de adição de um usuário ao emulador do Firebase Auth e, em seguida, fará login desse usuário por meio da IU do Flutter.

Adicionar um usuário

Clique no botão "Adicionar usuário" e preencha o formulário com estas informações:

  • Nome de exibição: Dash
  • E-mail: dash@email.com
  • Senha: Dashword

Envie o formulário e você verá que a tabela agora inclui um usuário. Agora você pode atualizar o código para fazer login com esse usuário.

log_out_view.dart

O único código no widget LoggedOutView que precisa ser atualizado está no retorno de chamada que é acionado quando um usuário pressiona o botão de login. Atualize o código para ficar assim:

class LoggedOutView extends StatelessWidget {
 final AppState state;
 const LoggedOutView({super.key, required this.state});
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: const Text('Firebase Emulator Suite Codelab'),
     ),
     body: Center(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: [
          Text(
           'Please log in',
            style: Theme.of(context).textTheme.displaySmall,
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: ElevatedButton(
             onPressed: () async {
              await state.logIn('dash@email.com', 'dashword').then((_) {
                if (state.user != null) {
                 context.go('/');
                }
              });
              },
              child: const Text('Log In'),
          ),
        ),
      ],
    ),
   ),
  );
 }
}

O código atualizado substitui as strings TODO pelo e-mail e senha que você criou no emulador de autenticação. E na próxima linha, a linha if(true) foi substituída por um código que verifica se state.user é nulo. O código em AppClass esclarece mais sobre isso.

app_state.dart

Duas partes do código em AppState precisam ser atualizadas. Primeiro, atribua ao membro da classe AppState.user o tipo User do pacote firebase_auth , em vez do tipo Object .

Em segundo lugar, preencha o método AppState.login conforme mostrado abaixo:

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'entry.dart';

class AppState {
 AppState() {
   _entriesStreamController = StreamController.broadcast(onListen: () {
     _entriesStreamController.add([
       Entry(
         date: '10/09/2022',
         text: lorem,
         title: '[Example] My Journal Entry',
       )
     ]);
   });
 }

 User? user; // <-- changed variable type
 Stream<List<Entry>> get entries => _entriesStreamController.stream;
 late final StreamController<List<Entry>> _entriesStreamController;

 Future<void> logIn(String email, String password) async {
   final credential = await FirebaseAuth.instance
       .signInWithEmailAndPassword(email: email, password: password);
   if (credential.user != null) {
     user = credential.user!;
     _listenForEntries();
   } else {
     print('no user!');
   }
 } 
 // ...
}

A definição de tipo para usuário agora é User? . Essa classe User vem do Firebase Auth e fornece as informações necessárias, como User.displayName , que será discutida em breve.

Este é o código básico necessário para fazer login de um usuário com e-mail e senha no Firebase Auth. Ele faz uma chamada para FirebaseAuth para fazer login, que retorna um objeto Future<UserCredential> . Quando o futuro for concluído, esse código verificará se há um User anexado ao UserCredential . Se houver um usuário no objeto de credencial, então um usuário efetuou login com êxito e a propriedade AppState.user poderá ser configurada. Se não houver, ocorreu um erro e será impresso.

Observe que a única linha de código neste método específica para este aplicativo (em vez do código geral do FirebaseAuth) é a chamada para o método _listenForEntries , que será abordado na próxima etapa.

TODO: Ícone de ação – Recarregue seu aplicativo e pressione o botão Login quando ele for renderizado. Isso faz com que o aplicativo navegue até uma página que diz “Bem-vindo de volta, pessoa!” no topo. A autenticação deve estar funcionando, pois permite navegar até esta página, mas uma pequena atualização precisa ser feita em logged_in_view.dart para exibir o nome real do usuário.

logado_in_view.dart

Altere a primeira linha no método LoggedInView.build :

class LoggedInView extends StatelessWidget {
 final AppState state;
 LoggedInView({super.key, required this.state});

 final PageController _controller = PageController(initialPage: 1);

 @override
 Widget build(BuildContext context) {
   final name = state.user!.displayName ?? 'No Name';

   return Scaffold(
 // ...

Agora, esta linha captura o displayName da propriedade User no objeto AppState . Este displayName foi definido no emulador quando você definiu seu primeiro usuário. Seu aplicativo agora deve exibir “Bem-vindo de volta, Dash!” quando você faz login, em vez de TODO .

6. Ler e gravar dados no emulador Firestore

Primeiro, confira o emulador Firestore. Na página inicial da IU do emulador ( localhost:4000 ), clique em "Ir para o emulador" no cartão Firestore. Deveria ficar assim:

Emulador:

791fce7dc137910a.png

Console do Firebase:

e0dde9aea34af050.png

Se você tiver alguma experiência com o Firestore, notará que esta página é semelhante à página do Firestore no console do Firebase. Existem algumas diferenças notáveis, no entanto.

  1. Você pode limpar todos os dados com o toque de um botão. Isso seria perigoso com dados de produção, mas é útil para iterações rápidas! Se você estiver trabalhando em um novo projeto e seu modelo de dados mudar, será fácil limpá-lo.
  2. Existe uma guia "Solicitações". Esta guia permite que você observe as solicitações recebidas feitas a este emulador. Discutirei essa guia com mais detalhes em breve.
  3. Não há guias para regras, índices ou uso. Existe uma ferramenta (discutida na próxima seção) que ajuda a escrever regras de segurança, mas você não pode definir regras de segurança para o emulador local.

Para resumir essa lista, esta versão do Firestore fornece mais ferramentas úteis durante o desenvolvimento e remove ferramentas necessárias na produção.

Escreva para o Firestore

Antes de discutir a guia ‘Solicitações’ no emulador, primeiro faça uma solicitação. Isso requer atualizações de código. Comece conectando o formulário no aplicativo para escrever uma nova Entry de diário no Firestore.

O fluxo de alto nível para enviar uma Entry é:

  1. O usuário preenche o formulário e pressiona o botão Submit
  2. A IU chama AppState.writeEntryToFirebase
  3. AppState.writeEntryToFirebase adiciona uma entrada ao Firebase

Nenhum código envolvido na etapa 1 ou 2 precisa ser alterado. O único código que precisa ser adicionado na etapa 3 será adicionado na classe AppState . Faça a seguinte alteração em AppState.writeEntryToFirebase .

app_state.dart

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'entry.dart';

class AppState {
 AppState() {
   _entriesStreamController = StreamController.broadcast(onListen: () {
     _entriesStreamController.add([
       Entry(
         date: '10/09/2022',
         text: lorem,
         title: '[Example] My Journal Entry',
       )
     ]);
   });
 }

 User? user;
 Stream<List<Entry>> get entries => _entriesStreamController.stream;
 late final StreamController<List<Entry>> _entriesStreamController;

 Future<void> logIn(String email, String password) async {
   final credential = await FirebaseAuth.instance
       .signInWithEmailAndPassword(email: email, password: password);
   if (credential.user != null) {
     user = credential.user!;
     _listenForEntries();
   } else {
     print('no user!');
   }
 }

 void writeEntryToFirebase(Entry entry) {
   FirebaseFirestore.instance.collection('Entries').add(<String, String>{
     'title': entry.title,
     'date': entry.date.toString(),
     'text': entry.text,
   });
 }
 // ...
}

O código no método writeEntryToFirebase obtém uma referência à coleção chamada “Entries” no Firestore. Em seguida, adiciona uma nova entrada, que precisa ser do tipo Map<String, String> .

Nesse caso, a coleção “Entradas” no Firestore não existia, então o Firestore criou uma.

Com esse código adicionado, recarregue ou reinicie seu aplicativo, faça login e navegue até a visualização EntryForm . Você pode preencher o formulário com as Strings que desejar. (O campo Date aceita qualquer String, pois foi simplificado para este codelab. Ele não tem validação forte nem se preocupa com objetos DateTime de forma alguma.)

Pressione enviar no formulário. Nada acontecerá no aplicativo, mas você poderá ver sua nova entrada na interface do emulador.

A guia de solicitações no emulador do Firestore

Na IU, navegue até o emulador do Firestore e observe a guia "Dados". Você verá que agora existe uma coleção na raiz do seu banco de dados chamada "Entradas". Deve haver um documento que contenha as mesmas informações que você inseriu no formulário.

a978fb34fb8a83da.png

Isso confirma que AppState.writeEntryToFirestore funcionou e agora você pode explorar melhor a solicitação na guia Solicitações. Clique nessa guia agora.

Solicitações de emulador do Firestore

Aqui, você deverá ver uma lista semelhante a esta:

f0b37f0341639035.png

Você pode clicar em qualquer um desses itens da lista e ver muitas informações úteis. Clique no item da lista CREATE que corresponde à sua solicitação para criar um novo lançamento contábil manual. Você verá uma nova tabela parecida com esta:

385d62152e99aad4.png

Conforme mencionado, o emulador Firestore fornece ferramentas para desenvolver as regras de segurança do seu aplicativo. Esta visualização mostra exatamente em qual linha das suas regras de segurança essa solicitação passou (ou falhou, se for o caso). Em um aplicativo mais robusto, as regras de segurança podem crescer e ter diversas verificações de autorização. Esta visualização é usada para ajudar a escrever e depurar essas regras de autorização.

Ele também fornece uma maneira fácil de inspecionar cada parte dessa solicitação, incluindo os metadados e os dados de autenticação. Esses dados são usados ​​para escrever regras de autorização complexas.

Lendo do Firestore

O Firestore usa sincronização de dados para enviar dados atualizados aos dispositivos conectados. No código Flutter, você pode ouvir (ou assinar) coleções e documentos do Firestore, e seu código será notificado sempre que os dados forem alterados. Neste aplicativo, a escuta das atualizações do Firestore é feita no método chamado AppState._listenForEntries .

Este código funciona em conjunto com StreamController e Stream chamados AppState._entriesStreamController e AppState.entries , respectivamente. Esse código já está escrito, assim como todo o código necessário na IU para exibir os dados do Firestore.

Atualize o método _listenForEntries para corresponder ao código abaixo:

app_state.dart

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'entry.dart';

class AppState {
 AppState() {
   _entriesStreamController = StreamController.broadcast(onListen: () {
     _entriesStreamController.add([
       Entry(
         date: '10/09/2022',
         text: lorem,
         title: '[Example] My Journal Entry',
       )
     ]);
   });
 }

 User? user;
 Stream<List<Entry>> get entries => _entriesStreamController.stream;
 late final StreamController<List<Entry>> _entriesStreamController;

 Future<void> logIn(String email, String password) async {
   final credential = await FirebaseAuth.instance
       .signInWithEmailAndPassword(email: email, password: password);
   if (credential.user != null) {
     user = credential.user!;
     _listenForEntries();
   } else {
     print('no user!');
   }
 }

 void writeEntryToFirebase(Entry entry) {
   FirebaseFirestore.instance.collection('Entries').add(<String, String>{
     'title': entry.title,
     'date': entry.date.toString(),
     'text': entry.text,
   });
 }

 void _listenForEntries() {
   FirebaseFirestore.instance
       .collection('Entries')
       .snapshots()
       .listen((event) {
     final entries = event.docs.map((doc) {
       final data = doc.data();
       return Entry(
         date: data['date'] as String,
         text: data['text'] as String,
         title: data['title'] as String,
       );
     }).toList();

     _entriesStreamController.add(entries);
   });
 }
 // ...
}

Este código escuta a coleção “Entries” no Firestore. Quando o Firestore notifica este cliente de que há novos dados, ele passa esses dados e o código em _listenForEntries transforma todos os seus documentos filhos em um objeto que nosso aplicativo pode usar ( Entry ). Em seguida, ele adiciona essas entradas ao StreamController chamado _entriesStreamController (que a UI está escutando). Este código é a única atualização necessária.

Por fim, lembre-se de que o método AppState.logIn faz uma chamada para _listenForEntries , que inicia o processo de escuta após o login do usuário.

// ...
Future<void> logIn(String email, String password) async {
 final credential = await FirebaseAuth.instance
     .signInWithEmailAndPassword(email: email, password: password);
 if (credential.user != null) {
   user = credential.user!;
   _listenForEntries();
 } else {
   print('no user!');
 }
}
// ...

Agora execute o aplicativo. Deveria ficar assim:

b8a31c7a8900331.gif

7. Exporte e importe dados para o emulador

Os emuladores do Firebase oferecem suporte à importação e exportação de dados. O uso de importações e exportações permite continuar o desenvolvimento com os mesmos dados quando você faz uma pausa no desenvolvimento e depois o retoma. Você também pode enviar arquivos de dados para o git, e outros desenvolvedores com quem você está trabalhando terão os mesmos dados para trabalhar.

Exportar dados do emulador

Primeiro, exporte os dados do emulador que você já possui. Enquanto os emuladores ainda estão em execução, abra uma nova janela de terminal e digite o seguinte comando:

firebase emulators:export ./emulators_data

.emulators_data é um argumento que informa ao Firebase para onde exportar os dados. Se o diretório não existir, ele será criado. Você pode usar qualquer nome que desejar para esse diretório.

Ao executar este comando, você verá esta saída no terminal onde executou o comando:

i  Found running emulator hub for project flutter-firebase-codelab-d6b79 at http://localhost:4400
i  Creating export directory /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data
i  Exporting data to: /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data
✔  Export complete

E se você mudar para a janela do terminal onde os emuladores estão sendo executados, você verá esta saída:

i  emulators: Received export request. Exporting data to /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data.
✔  emulators: Export complete.

E finalmente, se você olhar no diretório do seu projeto, deverá ver um diretório chamado ./emulators_data , que contém arquivos JSON , entre outros arquivos de metadados, com os dados que você salvou.

Importar dados do emulador

Agora você pode importar esses dados como parte do seu fluxo de trabalho de desenvolvimento e começar de onde parou.

Primeiro, pare os emuladores se eles estiverem em execução pressionando CTRL+C em seu terminal.

Em seguida, execute o comando emulators:start que você já viu, mas com um sinalizador informando quais dados importar:

firebase emulators:start --import ./emulators_data

Quando os emuladores estiverem ativos, navegue até a UI do emulador em localhost:4000 e você deverá ver os mesmos dados com os quais estava trabalhando anteriormente.

Exporte dados automaticamente ao fechar emuladores

Você também pode exportar dados automaticamente ao sair dos emuladores, em vez de se lembrar de exportar os dados ao final de cada sessão de desenvolvimento.

Ao iniciar seus emuladores, execute o comando emulators:start com dois sinalizadores adicionais.

firebase emulators:start --import ./emulators_data --export-on-exit

Voilá! Seus dados agora serão salvos e recarregados cada vez que você trabalhar com os emuladores deste projeto. Você também pode especificar um diretório diferente como argumento para o –export-on-exit flag , mas o padrão será o diretório passado para –import .

Você também pode usar qualquer combinação dessas opções. Esta é a observação dos documentos : O diretório de exportação pode ser especificado com este sinalizador: firebase emulators:start --export-on-exit=./saved-data . Se --import for usado, o caminho de exportação será o mesmo; por exemplo: firebase emulators:start --import=./data-path --export-on-exit . Por último, se desejar, passe caminhos de diretório diferentes para os sinalizadores --import e --export-on-exit .

8. Parabéns!

Você concluiu a instalação do emulador Firebase e do 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 Firebase
  • CLI do FlutterFire
  • CLI do Firebase
  • Emulador de autenticação Firebase
  • Emulador Firebase Firestore
  • Importando e exportando dados do emulador

Próximos passos

Saber mais

Sparky está orgulhoso de você!

2a0ad195769368b1.gif