1. 准备工作
在此 Codelab 中,您将学习如何在本地开发期间将 Firebase Emulator Suite 与 Flutter 搭配使用。您将了解如何通过 Emulator Suite 使用电子邮件地址/密码身份验证,以及如何在 Firestore 模拟器中读取和写入数据。最后,您将从模拟器中导入和导出数据,以便每次返回开发阶段时都使用相同的虚构数据。
前提条件
此 Codelab 假定您具有一些 Flutter 经验。如果没有,您可能需要先了解基础知识。以下链接非常有用:
您还应该具有一定的 Firebase 经验,但如果您从未将 Firebase 添加到过 Flutter 项目,也没有关系。如果您不熟悉 Firebase 控制台,或者完全不熟悉 Firebase,请先访问以下链接:
您将创建的内容
此 Codelab 将引导您构建一个简单的日记应用。该应用将有一个登录界面,以及一个可供您阅读过往日记条目和创建新日记条目的界面。
学习内容
您将学习如何开始使用 Firebase,以及如何将 Firebase Emulator 套件集成并使用到您的 Flutter 开发工作流中。本课将介绍以下 Firebase 主题:
请注意,我们仅在介绍 Firebase Emulator Suite 时介绍这些主题。此 Codelab 重点介绍了如何将 Firebase 项目添加到 Flutter 应用,以及如何使用 Firebase 模拟器套件进行开发。我们不会对 Firebase Authentication 或 Firestore 进行深入讨论。如果您不熟悉这些主题,我们建议您先学习 “了解 Firebase for Flutter”Codelab。
您需要满足的条件
- 熟悉 Flutter 并安装了 SDK
- Intellij JetBrains 或 VS Code 文本编辑器
- Google Chrome 浏览器(或您的其他首选 Flutter 目标开发平台)。本 Codelab 中的某些终端命令会假定您是在 Chrome 上运行应用)
2. 创建和设置 Firebase 项目
您需要完成的第一个任务是在 Firebase 的 Web 控制台中创建一个 Firebase 项目。此 Codelab 的绝大部分内容都将重点介绍 Emulator Suite,它使用本地运行的界面,但您必须先设置一个完整的 Firebase 项目。
创建 Firebase 项目
- 登录 Firebase 控制台。
- 在 Firebase 控制台中,点击添加项目(或创建项目),然后为您的 Firebase 项目输入一个名称(例如“Firebase-Flutter-Codelab”)。
- 点击各个项目创建选项。如果出现提示,请接受 Firebase 条款。跳过设置 Google Analytics 的步骤,因为您不会对此应用使用 Google Analytics。
如需详细了解 Firebase 项目,请参阅了解 Firebase 项目。
您正在构建的应用使用两款可用于 Flutter 应用的 Firebase 产品:
- Firebase Authentication:让用户可以登录到您的应用。
- Cloud Firestore:用于在云端保存结构化数据,并在数据发生变化时即时收到通知。
这两款产品需要进行特殊配置,或需要使用 Firebase 控制台启用。
启用 Cloud Firestore
Flutter 应用使用 Cloud Firestore 保存日记条目。
启用 Cloud Firestore:
- 在 Firebase 控制台的构建部分中,点击 Cloud Firestore。
- 点击创建数据库。
- 选择 Start in test mode 选项。阅读有关安全规则的免责声明。测试模式可确保您在开发过程中可以随意向数据库写入数据。点击下一步。
- 选择数据库的位置(只需使用默认值即可)。请注意,此位置以后无法更改。
- 点击启用。
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 项目的工具。您需要安装 CLI 才能使用 Emulator Suite,
您可以通过多种方式安装 CLI。如果您使用的是 MacOS 或 Linux,最简单的方法是从终端运行以下命令:
curl -sL https://firebase.tools | bash
安装 CLI 后,您必须进行 Firebase 身份验证。
- 运行以下命令,使用您的 Google 账号登录 Firebase:
firebase login
- 此命令将您的本地机器连接到 Firebase,并授予您对 Firebase 项目的访问权限。
- 通过列出 Firebase 项目来测试 CLI 是否已正确安装,以及是否有权访问您的账号:运行以下命令:
firebase projects:list
- 显示的列表应与 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
此命令会引导您完成设置项目所需的一系列问题。以下屏幕截图展示了该流程:
- 当系统提示您选择功能时,请选择“Firestore”和“模拟器”。(没有 Authentication 选项,因为它不使用可通过 Flutter 项目文件修改的配置。)
- 接下来,出现提示时选择“使用现有项目”。
- 现在,选择您在上一步中创建的项目:flutter-firebase-codelab。
- 接下来,系统会询问您一系列与要生成的文件命名相关的问题。建议按 Enter 键选择默认值。
- 最后,您需要配置模拟器。从列表中选择 Firestore 和 Authentication,然后按 Enter 键与每个模拟器使用的特定端口有关的每个问题。当系统询问您是否要使用模拟器界面时,您应选择默认选项“是”。
该过程结束后,您应该会看到如下屏幕截图所示的输出。
重要提示:您的输出结果可能与下方屏幕截图中的结果略有不同,因为如果您已下载模拟器,则最后一个问题将默认设为“否”。
配置 FlutterFire
接下来,您可以使用 FlutterFire 生成所需的 Dart 代码,以便在 Flutter 应用中使用 Firebase。
flutterfire configure
运行此命令时,系统会提示您选择要使用的 Firebase 项目以及要设置的平台。在此 Codelab 中,示例使用的是 Flutter Web,但您可以设置 Firebase 项目以使用所有选项。
以下屏幕截图显示了您需要回答的提示。
此屏幕截图显示了该过程结束时的输出。如果您熟悉 Firebase,就会发现您不必在控制台中创建应用,而 FlutterFire CLI 已为您代劳。
将 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.ensureInitialized
和 Firebase.initializeApp
。
接下来,if (kDebugMode)
行开头的代码会指示您的应用以模拟器为目标平台,而不是以正式版 Firebase 项目为目标平台。kDebugMode
可确保仅在您位于开发环境中时定位到模拟器。由于 kDebugMode
是一个常量值,因此 Dart 编译器知道在发布模式下完全移除该代码块。
启动模拟器
您应先启动模拟器,然后再启动 Flutter 应用。首先,在终端中运行以下命令以启动模拟器:
firebase emulators:start
此命令会启动模拟器,并公开本地主机端口,以便我们与模拟器进行交互。运行该命令后,您应该会看到类似以下内容的输出:
此输出会告知您哪些模拟器正在运行,以及您可以在哪里查看模拟器。首先,查看位于 localhost:4000
的模拟器界面。
这是本地模拟器界面的首页。该页面会列出所有可用的模拟器,并为每个模拟器标注启用或停用状态。
5. Firebase Auth 模拟器
您将使用的第一个模拟器是 Authentication 模拟器。点击“前往模拟器”以启动 Auth 模拟器您将看到如下所示的页面:
此页面与 Auth 网页控制台页面类似。该工具会显示一个表格,其中列出了用户(与在线控制台类似),并且允许您手动添加用户。这里的一个最大区别是,模拟器上唯一可用的身份验证方法选项是电子邮件地址和密码。这对于本地开发已经足够了。
接下来,您将详细了解如何向 Firebase Authentication 模拟器添加用户,然后通过 Flutter 界面登录该用户。
添加用户
点击“添加用户”按钮,然后使用以下信息填写表单:
- 显示名称:Dash
- 电子邮件:dash@email.com
- 密码:dashword
提交表单,您将看到表格中现在包含一个用户。现在,您可以更新代码以使用该用户登录。
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 Auth,并提供所需的信息,例如 User.displayName
(稍后我们将对此进行介绍)。
这是在 Firebase Authentication 中使用电子邮件地址和密码登录用户所需的基本代码。它会调用 FirebaseAuth 进行登录,然后返回一个 Future<UserCredential>
对象。未来完成时,此代码会检查 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!”(欢迎回来,Dash!)而不是 TODO
。
6. 对 Firestore 模拟器执行数据读写操作
首先,查看 Firestore 模拟器。在模拟器界面首页 (localhost:4000
) 上,点击 Firestore 卡片上的“前往模拟器”。它应如下所示:
模拟器:
Firebase 控制台:
如果您曾使用过 Firestore,会注意到此页面类似于 Firebase 控制台的 Firestore 页面。不过,这两者之间存在一些显著的差异。
- 只需点按一下按钮即可清除所有数据。这对于生产数据来说很危险,但对于快速迭代很有帮助!如果您正在处理新项目,并且数据模型发生变化,这很容易清除。
- 有一个“请求”标签页。通过此标签页,您可以监控向此模拟器发出的传入请求。我将更详细地介绍此标签。
- 没有“规则”“索引”或“使用情况”标签页。有一个工具(将在下一部分讨论)可帮助您编写安全规则,但您无法为本地模拟器设置安全规则。
总而言之,此版本的 Firestore 提供了更多在开发过程中有用的工具,并移除了生产环境中所需的工具。
写入 Firestore
在讨论模拟器中的“请求”标签页之前,请先发出请求。这需要更新代码。首先在应用中连接表单,以便将新日志 Entry
写入 Firestore。
提交 Entry
的大致流程如下:
- 用户填写表单并按下“
Submit
”按钮 - 界面调用
AppState.writeEntryToFirebase
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 中的“条目”集合不存在,因此 Firestore 创建了一个。
添加该代码后,热重载或重启应用,登录并导航到 EntryForm
视图。您可以根据需要在表单中填写任何Strings
。(Date 字段将采用任何字符串,因为在此 Codelab 中,该字段已进行了简化。它没有强制验证,也不会以任何方式关心 DateTime
对象。)
在表单上按“提交”。应用中不会发生任何变化,但您可以在模拟器界面中看到新条目。
Firestore 模拟器中的“请求”标签页
在界面中,前往 Firestore 模拟器,然后查看“Data”标签页。您应该会看到数据库根目录中现在有一个名为“Entries”的集合。这份表单应包含您在表单中输入的信息。
这确认了 AppState.writeEntryToFirestore
已正常运行,现在您可以在“请求”标签页中进一步了解该请求。立即点击该标签页。
Firestore 模拟器请求
在这里,您应该看到一个类似如下所示的列表:
您可以点击进入这些列表项,看到很多有用的信息。点击与您的请求对应的 CREATE
列表项,以创建新的日记条目。您将看到如下所示的新表:
如前所述,Firestore 模拟器提供了用于开发应用安全规则的工具。此视图会准确显示此请求通过(或失败,如果是这种情况)的安全规则中的哪一行。在更强大的应用中,安全规则可以扩展并包含多项授权检查。此视图用于帮助编写和调试这些授权规则。
它还提供了一种简单方法来检查此请求的每一部分,包括元数据和身份验证数据。这些数据用于编写复杂的授权规则。
从 Firestore 读取数据
Firestore 使用数据同步功能将更新后的数据推送到已连接的设备。在 Flutter 代码中,您可以监听(或订阅)Firestore 集合和文档,这样每当数据发生更改时,您的代码都会收到通知。在此应用中,监听 Firestore 更新是在名为 AppState._listenForEntries
的方法中完成的。
此代码分别与名为 AppState._entriesStreamController
和 AppState.entries
的 StreamController
和 Stream
结合使用。该代码已编写完毕,界面中显示 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 中的“条目”集合。当 Firestore 通知此客户端有新数据时,它会传递这些数据,并且 _listenForEntries
中的代码会将其所有子文档更改为我们的应用可以使用的对象 (Entry
)。然后,它会将这些条目添加到名为 _entriesStreamController
的 StreamController
(界面正在监听该 _entriesStreamController
)。只需要更新此代码。
最后,回想一下,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!'); } } // ...
现在运行应用。代码应如下所示:
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”。您可以在“complete”(完成)中找到此 Codelab 的完整代码GitHub 上的目录:Flutter Codelab
所学内容
- 设置 Flutter 应用以使用 Firebase
- 设置 Firebase 项目
- FlutterFire CLI
- Firebase CLI
- Firebase Authentication 模拟器
- Firebase Firestore 模拟器
- 导入和导出模拟器数据
后续步骤
- 详细了解如何在 Flutter 中使用 Firestore 和 Authentication:“了解如何将 Firebase 用于 Flutter”Codelab
- 探索其他提供模拟器的 Firebase 工具:
- Cloud Storage
- Cloud Functions
- Realtime Database
- 探索 FlutterFire 界面,快速将 Google Authentication 添加到您的应用。
了解详情
- Firebase 网站:firebase.google.com
- Flutter 网站:flutter.dev
- FlutterFire Firebase Flutter widget:firebase.flutter.dev
- Firebase YouTube 频道
- Flutter YouTube 频道
Sparky 为您感到骄傲!