使用 Firebase Emulator Suite 在本地开发 Flutter 应用

1. 准备工作

在此 Codelab 中,您将学习如何在本地开发过程中将 Firebase Emulator Suite 与 Flutter 搭配使用。您将学习如何通过 Emulator Suite 使用电子邮件地址/密码身份验证,以及如何在 Firestore 模拟器中读取和写入数据。最后,您将从模拟器中导入和导出数据,以便在每次返回开发时处理相同的虚构数据。

前提条件

此 Codelab 假定您具有一些 Flutter 经验。如果没有,您可能需要先了解基础知识。以下链接非常有用:

您还应具备一定程度的 Firebase 经验,但如果您从未将 Firebase 添加到 Flutter 项目,也没有关系。如果您不熟悉 Firebase 控制台,或者第一次使用 Firebase,请先查看以下链接:

您将创建的内容

此 Codelab 将指导您构建一个简单的日记应用。该应用将具有一个登录屏幕,以及一个可让您阅读过去的日记条目和创建新条目的屏幕。

cd5c4753bbee8af.png 8cb4d21f656540bf.png

学习内容

您将学习如何开始使用 Firebase,以及如何将 Firebase Emulator Suite 集成到和使用 Flutter 开发工作流中。我们将介绍以下 Firebase 主题:

请注意,仅涵盖介绍 Firebase Emulator Suite 所必需的主题。此 Codelab 将重点介绍如何将 Firebase 项目添加到您的 Flutter 应用,以及使用 Firebase Emulator Suite 进行开发。我们不会深入讨论 Firebase Authentication 或 Firestore。如果您不熟悉这些主题,建议您从“了解适用于 Flutter 的 Firebase”Codelab 开始学习。

所需条件

  • 具备 Flutter 的实际运用知识,并且已安装 SDK
  • Intellij JetBrains 或 VS Code 文本编辑器
  • Google Chrome 浏览器(或您的其他首选 Flutter 开发目标。此 Codelab 中的一些终端命令将假定您在 Chrome 上运行应用)

2. 创建和设置 Firebase 项目

您需要完成的第一项任务是在 Firebase 的 Web 控制台中创建一个 Firebase 项目。此 Codelab 的大部分内容都将重点介绍 Emulator Suite,该套件使用本地运行的界面,但您必须先设置完整的 Firebase 项目。

创建 Firebase 项目

  1. 登录 Firebase 控制台。
  2. 在 Firebase 控制台中,点击添加项目(或创建项目),然后为您的 Firebase 项目输入一个名称(例如“Firebase-Flutter-Codelab”)。

fe6aeab3b91965ed

  1. 点击各个项目创建选项。如果系统提示,请接受 Firebase 条款。跳过设置 Google Analytics(分析)的步骤,因为您不会为此应用使用 Google Analytics(分析)。

d1fcec48bf251eaa.png

如需详细了解 Firebase 项目,请参阅了解 Firebase 项目

您正在构建的应用使用了两个适用于 Flutter 应用的 Firebase 产品:

  • Firebase Authentication:允许用户登录您的应用。
  • Cloud Firestore:用于将结构化数据保存在云端,并在数据发生变化时收到即时通知。

这两个产品需要特殊配置或者需要使用 Firebase 控制台启用。

启用 Cloud Firestore

Flutter 应用使用 Cloud Firestore 保存日记条目。

启用 Cloud Firestore:

  1. 在 Firebase 控制台的 Build 部分中,点击 Cloud Firestore
  2. 点击创建数据库99e8429832d23fa3
  3. 选择以测试模式开始选项。阅读有关安全规则的免责声明。测试模式可确保您在开发过程中可以随意向数据库写入数据。点击 Next6be00e26c72ea032
  4. 选择数据库的位置(只需使用默认位置即可)。请注意,此位置以后无法更改。278656eefcfb0216
  5. 点击启用

3. 设置 Flutter 应用

在我们开始之前,您需要下载起始代码并安装 Firebase CLI。

获取起始代码

从命令行克隆 GitHub 代码库

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

或者,如果您已安装 GitHub 的 cli 工具,请运行以下命令:

gh repo clone flutter/codelabs flutter-codelabs

您应将示例代码克隆到 flutter-codelabs 目录中,该目录包含一系列 Codelab 的代码。此 Codelab 的代码位于 flutter-codelabs/firebase-emulator-suite 中。

flutter-codelabs/firebase-emulator-suite 下的目录结构由两个 Flutter 项目组成。一个名为 complete,如果您想跳过,或者交叉引用您自己的代码,可以引用它。另一个项目名为 start

您希望起始代码位于 flutter-codelabs/firebase-emulator-suite/start 目录中。打开该目录,或将该目录导入您的首选 IDE。

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

安装 Firebase CLI

Firebase CLI 提供了用于管理 Firebase 项目的工具。如需使用 Emulator Suite,需要安装 CLI,因此您需要安装。

您可以通过多种方式安装 CLI。如果您使用的是 MacOS 或 Linux,最简单的方法是从终端运行此命令:

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

安装 CLI 后,您必须进行 Firebase 身份验证。

  1. 运行以下命令,使用您的 Google 账号登录 Firebase:
firebase login
  1. 此命令会将您的本地机器与 Firebase 关联,并授予您对 Firebase 项目的访问权限。
  1. 列出您的 Firebase 项目,测试 CLI 是否已正确安装以及是否可以访问您的帐号。运行以下命令:
firebase projects:list
  1. 显示的列表应与 Firebase 控制台中列出的 Firebase 项目相同。您应该至少看到 firebase-flutter-codelab。

安装 FlutterFire CLI

FlutterFire CLI 基于 Firebase CLI 构建,可让您更轻松地将 Firebase 项目与 Flutter 应用集成。

首先,安装 CLI:

dart pub global activate flutterfire_cli

确保已安装 CLI。在 Flutter 项目目录中运行以下命令,并确保 CLI 会输出帮助菜单。

flutterfire --help

使用 Firebase CLI 和 FlutterFire CLI 将 Firebase 项目添加到您的 Flutter 应用

安装这两个 CLI 后,您只需使用几个终端命令,即可设置各个 Firebase 产品(如 Firestore)、下载模拟器,以及将 Firebase 添加到您的 Flutter 应用。

首先,运行以下命令完成 Firebase 设置:

firebase init

此命令将引导您回答设置项目所需的一系列问题。以下屏幕截图展示了该流程:

  1. 当系统提示您选择功能时,请选择“Firestore”和“模拟器”。(没有 Authentication 选项,因为它不使用可从 Flutter 项目文件修改的配置。)fe6401d769be8f53
  2. 接下来,在出现提示时选择“使用现有项目”。

f11dcab439e6ac1e.png

  1. 现在,选择您在上一步中创建的项目:flutter-firebase-codelab。

3bdc0c6934991c25

  1. 接下来,系统会询问您一系列关于为将生成的文件命名的问题。建议您为每个问题按下“Enter”键以选择默认题目。9bfa2d507e199c59
  2. 最后,您需要配置模拟器。从列表中选择“Firestore 和 Authentication”,然后按“Enter”键,回答与要用于每个模拟器的特定端口有关的每个问题。当系统询问您是否要使用模拟器界面时,您应选择默认值,即“是”。

在完成此过程后,您应该会看到类似于以下屏幕截图的输出。

重要提示:您的输出可能与我的输出略有不同,如以下屏幕截图所示,因为如果您已下载模拟器,最后一个问题将默认为“No”。

8544e41037637b07

配置 FlutterFire

接下来,您可以使用 FlutterFire 生成所需的 Dart 代码,以便在您的 Flutter 应用中使用 Firebase。

flutterfire configure

运行此命令时,系统会提示您选择要使用的 Firebase 项目以及要设置的平台。在此 Codelab 中,示例使用的是 Flutter Web,但您可以将 Firebase 项目设置为使用所有选项。

以下屏幕截图显示了您需要回答的提示。

619b7aca6dc15472 301c9534f594f472

此屏幕截图显示了此过程结束时的输出。如果您熟悉 Firebase,就会发现不必在控制台中创建应用,FlutterFire CLI 会为您代劳。

12199a85ade30459

将 Firebase 软件包添加到 Flutter 应用

最后一步是将相关的 Firebase 软件包添加到您的 Flutter 项目。在终端中,确保您位于 Flutter 项目的根目录 flutter-codelabs/firebase-emulator-suite/start。然后,运行以下三个命令:

flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add cloud_firestore

这些是您将在此应用中使用的唯一软件包。

4.启用 Firebase 模拟器

到目前为止,Flutter 应用和您的 Firebase 项目已设置为能够使用模拟器,但您仍然需要告知 Flutter 代码将传出的 Firebase 请求重新路由到本地端口。

首先,将 Firebase 初始化代码和模拟器设置代码添加到 main.dart. 中的 main 函数

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

前几行代码用于初始化 Firebase。几乎普遍的做法是,如果您在 Flutter 应用中使用 Firebase,需要先调用 WidgetsFlutterBinding.ensureInitializedFirebase.initializeApp

之后,以 if (kDebugMode) 行开头的代码会指示您的应用以模拟器为目标,而不是正式版 Firebase 项目。kDebugMode 可确保仅在您处于开发环境时才会定位到模拟器。由于 kDebugMode 是一个常量值,因此 Dart 编译器知道在发布模式下完全移除该代码块。

启动模拟器

您应先启动模拟器,然后再启动 Flutter 应用。首先,在终端中运行以下命令来启动模拟器:

firebase emulators:start

此命令会启动模拟器,并显示 localhost 端口,以便我们与其进行交互。运行该命令时,您应该会看到类似如下所示的输出:

bb7181eb70829606

此输出信息可告诉您哪些模拟器正在运行,以及您可以在哪里查看模拟器。首先,查看位于 localhost:4000 的模拟器界面。

11563f4c7216de81.png

这是本地模拟器界面的首页。它会列出所有可用的模拟器,每个模拟器都带有开启或关闭状态标签。

5. Firebase Auth 模拟器

您将使用的第一个模拟器是 Authentication 模拟器。点击界面中“Authentication”卡片上的“Go to emulator”以开始使用 Auth 模拟器,您将看到如下所示的页面:

3c1bfded40733189

此页面与 Auth 网页版控制台页面具有一些相似之处。它有一个表格,和在线控制台一样列出用户,并且允许您手动添加用户。这里的一个很大区别是,模拟器上可用的唯一身份验证方法选项是电子邮件地址和密码。这足以进行本地开发。

接下来,您将完成向 Firebase Auth 模拟器添加用户的过程,然后通过 Flutter 界面使该用户登录。

添加用户

点击“添加用户”按钮,然后在表单中填写以下信息:

  • 显示名称:Dash
  • 电子邮件地址: dash@email.com
  • 密码:短划线

提交表单,您会看到表中现在包含一个用户。现在,您可以更新代码以使用该用户身份登录。

logged_out_view.dart

LoggedOutView widget 中唯一需要更新的代码位于用户按登录按钮时触发的回调中。将代码更新为如下所示:

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

更新后的代码会将 TODO 字符串替换为您在身份验证模拟器中创建的电子邮件地址和密码。在下一行代码中,if(true) 行已被替换为用于检查 state.user 是否为 null 的代码。AppClass 中的代码进一步说明了这一问题。

app_state.dart

AppState 中代码的两部分需要更新。首先,为类成员 AppState.user 提供 firebase_auth 软件包中的类型 User,而不是 Object 类型。

然后,填写 AppState.login 方法,如下所示:

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!');
   }
 } 
 // ...
}

用户的类型定义现在为 User?。该 User 类来自 Firebase Authentication,并提供 User.displayName 等所需信息,我们将对此进行详细介绍。

这是在 Firebase Auth 中使用电子邮件地址和密码登录用户所需的基本代码。它会调用 FirebaseAuth 进行登录,这会返回一个 Future<UserCredential> 对象。当 Future 变成已完成状态时,此代码会检查 UserCredential 上是否附加了 User。如果凭据对象上有用户,则表示用户已成功登录,您可以设置 AppState.user 属性。如果没有,则表示出现错误,并且输出结果。

请注意,此方法中唯一专用于此应用的代码行(而不是常规 FirebaseAuth 代码)是对 _listenForEntries 方法的调用,将在下一步中介绍。

待办事项:操作图标 - 重新加载您的应用,然后在呈现时按“登录”按钮。这会导致应用转到顶部显示“Welcome Back, Person!”的页面。身份验证必须正常运行,因为您可以使用它导航到此页面,但需要对 logged_in_view.dart 进行细微更新,以显示用户的真实姓名。

logged_in_view.dart

更改 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(
 // ...

现在,下面这行代码会从 AppState 对象的 User 属性中获取 displayName。此 displayName 是在定义第一位用户时在模拟器中设置的。现在,当您登录时,您的应用应显示“Welcome back, Dash!”,而不是 TODO

6. 对 Firestore 模拟器执行数据读写操作

首先,查看 Firestore 模拟器。在模拟器界面首页 (localhost:4000),点击 Firestore 卡片上的“转到模拟器”。它应如下所示:

模拟器:

791fce7dc137910a

Firebase 控制台:

e0dde9aea34af050.png

如果您有任何使用 Firestore 的经验,就会发现此页面与 Firebase 控制台的 Firestore 页面类似。不过,这两者之间有一些显著的差异。

  1. 只需点按一下按钮,即可清除所有数据。这对于生产数据来说很危险,但有助于快速迭代!如果您正在处理新项目,并且数据模型发生了变化,则很容易清除。
  2. 有一个“请求”标签页。通过此标签页,您可以监视向此模拟器发出的传入请求。稍后,我将更详细地讨论此标签。
  3. 没有针对“规则”、“索引”或“使用情况”的标签页。有一种工具(在下一部分会对此进行讨论)可帮助编写安全规则,但您无法为本地模拟器设置安全规则。

总而言之,此版本的 Firestore 提供了更多在开发过程中实用的工具,并移除了生产环境中所需的工具。

写入 Firestore

在讨论模拟器中的“Requests”标签页之前,请先发出请求。这需要更新代码。首先在应用中连接表单,将新日志 Entry 写入 Firestore。

提交 Entry 的大致流程如下:

  1. 用户填写表单并按了“Submit”按钮
  2. 界面调用 AppState.writeEntryToFirebase
  3. AppState.writeEntryToFirebase 向 Firebase 添加一个条目

第 1 步或第 2 步所涉及的代码均无需更改。需要为第 3 步添加的唯一代码将添加到 AppState 类中。对 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,
   });
 }
 // ...
}

writeEntryToFirebase 方法中的代码会获取对 Firestore 中名为“Entries”(条目)的集合的引用。然后,它会添加一个新条目,该条目必须为 Map<String, String> 类型。

在这种情况下,Firestore 中不存在“Entries”集合,因此 Firestore 创建了一个集合。

添加该代码后,执行热重载或重启应用,登录并转到 EntryForm 视图。您可以在表单中填写自己喜欢的任何 Strings。(“Date”字段可接受任何字符串,因为在此 Codelab 中已简化。它没有进行强有力的验证,也未以任何方式关注 DateTime 对象。)

在表单上按“提交”。应用不会执行任何操作,但您可以在模拟器界面中查看新条目。

Firestore 模拟器中的“请求”标签页

在界面中,转到 Firestore 模拟器并查看“Data”标签页。您应该会看到,数据库的根目录下现在有一个名为“Entries”(条目)的集合。其中应该有一份文档,其中包含您在表单中输入的信息。

A978fb34fb8a83da

这确认了 AppState.writeEntryToFirestore 有效,现在,您可以在“Requests”标签页中进一步浏览该请求。现在点击该标签页。

Firestore 模拟器请求

在这里,您应该会看到类似于以下内容的列表:

F0b37f0341639035

您可以点击进入其中任一列表项,查看很多有用的信息。点击与创建新日记条目的请求对应的 CREATE 列表项。您将看到一个如下所示的新表格:

385d62152e99aad4.png

如上所述,Firestore 模拟器提供了用于开发应用安全规则的工具。此视图准确显示了该请求通过(或失败,如果是这种情况)的安全规则中的哪一行。在更强大的应用中,安全规则可能会扩展且会进行多次授权检查。此视图用于帮助编写和调试这些授权规则。

它还提供了一种简单的方法来检查此请求的每一部分,包括元数据和身份验证数据。此数据用于编写复杂的授权规则。

从 Firestore 读取数据

Firestore 使用数据同步功能将更新后的数据推送到已连接的设备。在 Flutter 代码中,您可以监听(或订阅)Firestore 集合和文档,每当数据发生更改时,您的代码都会收到通知。在此应用中,在名为 AppState._listenForEntries 的方法中监听 Firestore 更新。

此代码分别与名为 AppState._entriesStreamControllerAppState.entriesStreamControllerStream 结合使用。该代码已经编写好,界面中显示 Firestore 数据所需的所有代码也是如此。

更新 _listenForEntries 方法以匹配以下代码:

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);
   });
 }
 // ...
}

此代码会监听 Firestore 中的“Entries”集合。当 Firestore 通知此客户端有新数据时,它会传递该数据,并且 _listenForEntries 中的代码会将其所有子文档更改为可供应用使用的对象 (Entry)。然后,它会将这些条目添加到名为 _entriesStreamControllerStreamController(界面正在监听)中。此代码是唯一需要的更新。

最后,回想一下 AppState.logIn 方法会调用 _listenForEntries,这会在用户登录后开始监听过程。

// ...
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!');
 }
}
// ...

现在运行应用。它应如下所示:

b8a31c7a8900331.gif

7. 将数据导入模拟器

Firebase 模拟器支持导入和导出数据。通过使用导入和导出,您可以在开发暂停后继续执行开发,使用相同的数据继续开发。您还可以将数据文件提交到 Git,与您合作的其他开发者也可以使用相同的数据。

导出模拟器数据

首先,导出已有的模拟器数据。在模拟器仍在运行时,打开一个新的终端窗口,然后输入以下命令:

firebase emulators:export ./emulators_data

.emulators_data 是一个参数,用于告知 Firebase 导出数据的位置。如果该目录不存在,系统会创建一个。您可以为该目录使用您喜欢的任何名称。

运行此命令后,您会在运行此命令的终端中看到以下输出:

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

如果您切换到运行模拟器的终端窗口,将会看到以下输出:

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

最后,如果查看项目目录,您应该会看到一个名为 ./emulators_data 的目录,其中包含 JSON 文件和其他元数据文件,以及您已保存的数据。

导入模拟器数据

现在,您可以在开发工作流中导入这些数据,并从上次停下的地方继续。

首先,在终端中按 CTRL+C 以停止正在运行的模拟器。

接下来,运行您之前看到的 emulators:start 命令,但这次使用一个标志来指示它要导入哪些数据:

firebase emulators:start --import ./emulators_data

模拟器启动后,前往位于 localhost:4000 的模拟器界面,您应该会看到与之前使用的相同数据。

关闭模拟器时自动导出数据

您还可以在退出模拟器时自动导出数据,无需在每次开发会话结束时导出数据。

启动模拟器时,请运行 emulators:start 命令并添加两个额外的标志。

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

瞧!现在,每当您为此项目使用模拟器时,系统都会保存并重新加载您的数据。您还可以指定其他目录作为 –export-on-exit flag 的参数,但该目录默认为传递给 –import 的目录。

您还可以使用这些选项的任意组合。以下是文档备注:可以使用 firebase emulators:start --export-on-exit=./saved-data 标志指定导出目录。如果使用 --import,则导出路径默认为相同;例如:firebase emulators:start --import=./data-path --export-on-exit。最后,如果需要,将不同的目录路径传递给 --import--export-on-exit 标志。

8. 恭喜!

您已完成 Firebase 模拟器和 Flutter 的使用入门。您可以在 GitHub 上的“complete”目录中找到此 Codelab 完成后的代码:Flutter Codelab

所学内容

  • 设置 Flutter 应用以使用 Firebase
  • 设置 Firebase 项目
  • FlutterFire CLI
  • Firebase CLI
  • Firebase Authentication 模拟器
  • Firebase Firestore 模拟器
  • 导入和导出模拟器数据

后续步骤

了解详情

Sparky 为你感到骄傲!

2a0ad195769368b1.gif