欢迎参加我们将于 2022 年 10 月 18 日举办的 Firebase 峰会(线上线下同时进行),了解 Firebase 如何帮助您加快应用开发速度、满怀信心地发布应用并在之后需要时轻松地扩大应用规模。立即报名

将您的应用连接到 Cloud Firestore 模拟器

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

在将您的应用连接到 Cloud Firestore 模拟器之前,请确保您了解 Firebase Local Emulator Suite 的整体工作流,而且已安装和配置 Local Emulator Suite 并已查看其 CLI 命令

选择一个 Firebase 项目

Firebase Local Emulator Suite 模拟的是单个 Firebase 项目的产品。

如需选择要使用的项目,请在启动模拟器之前,使用 CLI 在工作目录下运行 firebase use。或者,您可以将 --project 标志传递给每个模拟器命令。

Local Emulator Suite 支持模拟实际 Firebase 项目和演示项目。

项目类型 特性 与模拟器结合使用
实际项目

实际的 Firebase 项目就是您创建和配置的项目(很可能是通过 Firebase 控制台创建和配置)。

实际项目具有实时资源,例如数据库实例、存储桶、函数或您为该 Firebase 项目设置的任何其他资源。

使用实际的 Firebase 项目时,您可以为任何或所有受支持的产品运行模拟器。

对于您未模拟的任何产品,您的应用和代码都将与实时资源(数据库实例、存储桶、函数等)交互。

演示项目

演示 Firebase 项目没有实际 Firebase 配置,也没有实时资源。通常可通过 Codelab 或其他教程来访问这些项目。

演示项目的 ID 带有 demo- 前缀。

使用演示 Firebase 项目时,您的应用和代码仅与模拟器交互。如果您的应用尝试与您没有为其运行模拟器的资源进行交互,该代码将失败。

我们建议您尽可能使用演示项目。演示项目具有以下优势:

  • 设置更简单,您无需创建 Firebase 项目也可运行模拟器
  • 安全性更强,就算您的代码意外调用了非模拟(生产)资源,也不可能发生数据更改、资源使用或产生费用
  • 提供更好的离线支持,无需访问互联网即可下载您的 SDK 配置。

对您的应用进行插桩 (instrument) 处理以与模拟器通信

Android、Apple 平台和 Web SDK

按照以下步骤设置您的应用内配置或测试类,以便与 Cloud Firestore 进行交互。

Android
// 10.0.2.2 is the special IP address to connect to the 'localhost' of
// the host computer from an Android emulator.
FirebaseFirestore firestore = FirebaseFirestore.getInstance();
firestore.useEmulator("10.0.2.2", 8080);

FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
        .setPersistenceEnabled(false)
        .build();
firestore.setFirestoreSettings(settings);
Swift
let settings = Firestore.firestore().settings
settings.host = "localhost:8080"
settings.isPersistenceEnabled = false
settings.isSSLEnabled = false
Firestore.firestore().settings = settings

Web version 9

import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";

// firebaseApps previously initialized using initializeApp()
const db = getFirestore();
connectFirestoreEmulator(db, 'localhost', 8080);

Web version 8

// Firebase previously initialized using firebase.initializeApp().
var db = firebase.firestore();
if (location.hostname === "localhost") {
  db.useEmulator("localhost", 8080);
}

使用模拟器测试由 Firestore 事件触发的 Cloud Functions 函数时无需进行额外设置。当 Firestore 和 Cloud Functions 模拟器都在运行时,它们会自动协同工作。

Admin SDK

设置 FIRESTORE_EMULATOR_HOST 环境变量后,Firebase Admin SDK 会自动连接到 Cloud Firestore 模拟器:

export FIRESTORE_EMULATOR_HOST="localhost:8080"

如果您的代码在 Cloud Functions 模拟器中运行,系统会在调用 initalizeApp 时自动设置您的项目 ID 和其他配置。

如果您希望 Admin SDK 代码连接到在其他环境中运行的共享模拟器,则需要指定您使用 Firebase CLI 设置的同一项目 ID。您可以直接将项目 ID 传递给 initializeApp 或设置 GCLOUD_PROJECT 环境变量。

Node.js Admin SDK
admin.initializeApp({ projectId: "your-project-id" });
环境变量
export GCLOUD_PROJECT="your-project-id"

在两轮测试的间隙清空数据库

Firestore 生产实例不提供用于刷新 (flush) 数据库的平台 SDK 方法,但 Firestore 模拟器提供一个专用于此目的的 REST 端点,您可通过测试框架的“setup/tearDown”步骤、测试类或 shell(例如使用 curl)调用此端点,然后再开始测试。此方法可用作停止模拟器进程的替代方法。

在相应的方法中,执行 HTTP DELETE 操作,将您的 Firebase projectID(例如 firestore-emulator-example)提供给以下端点:

"http://localhost:8080/emulator/v1/projects/firestore-emulator-example/databases/(default)/documents"

当然,您的代码应等待关于刷新完成或失败的 REST 确认信息。

您可以通过 shell 执行此操作:

// Shell alternative…
$ curl -v -X DELETE "http://localhost:8080/emulator/v1/projects/firestore-emulator-example/databases/(default)/documents"

在完成类似的步骤后,您可以对测试进行排序并触发函数,确保清除多轮运行之间的旧数据,并且您使用的是新的基准测试配置。

导入和导出数据

借助数据库和 Cloud Firestore 模拟器,您可以从正在运行的模拟器实例中导出数据。定义要在单元测试或持续集成工作流中使用的基准数据集,然后将其导出以供团队共享。

firebase emulators:export ./dir

在测试中,当模拟器启动时,导入基准数据。

firebase emulators:start --import=./dir

您可以指示模拟器在关停时导出数据,方法是指定导出路径,或是直接使用传递给 --import 标志的路径。

firebase emulators:start --import=./dir --export-on-exit

这些数据导入和导出选项也适用于 firebase emulators:exec 命令。如需了解详情,请参阅模拟器命令参考文档

直观呈现安全规则活动

在完成原型设计和测试循环的过程中,您可以使用 Local Emulator Suite 提供的可视化工具和报告。

使用请求监控器

借助 Cloud Firestore 模拟器,您可以在 Emulator Suite 界面中直观呈现客户端请求,包括对 Firebase 安全规则的评估跟踪。

打开“Firestore”>“请求”标签页,以查看每个请求的详细评估序列。

显示安全规则评估的 Firestore 模拟器请求监控器

直观呈现规则评估报告

在向原型设计添加安全规则时,您可以使用 Local Emulator Suite 调试工具调试这些规则。

运行一系列测试后,您可以访问测试范围报告,其中显示了每个安全规则的评估结果。

如需获取该报告,请在模拟器运行时查询其上的公开端点。如需适用于浏览器的版本,请使用以下网址:

http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage.html

这会将您的规则分解为表达式和子表达式,您可以将鼠标悬停在相应表达式上以了解更多信息(包括评估次数和返回的值)。如需这些数据的原始 JSON 版本,请在查询中包含以下网址:

http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage

此处的 HTML 版本报告突出显示了抛出未定义和空值错误的评估:

Cloud Firestore 模拟器与生产环境的区别

Cloud Firestore 模拟器会尝试真实地重现生产服务的行为,但存在一些值得注意的限制。

事务

模拟器目前并不能实现生产环境中发生的所有事务行为。当您要测试涉及对一个文档执行多次并发写入的功能时,模拟器完成写入请求的速度可能会很慢。在某些情况下,对数据的锁定可能需要长达 30 秒才会解除。如有需要,请考虑相应地调整测试超时。

索引

模拟器不会跟踪复合索引,而是执行任何有效查询。请务必对真实的 Cloud Firestore 实例测试您的应用,以确定您需要哪些索引。

限制

模拟器不会强制执行生产环境中强制执行的所有限制。例如,模拟器可能允许会因为过大而会被生产服务拒绝的事务。请确保您熟悉文档中说明的限制,并且将您的应用设计为主动避免这些限制。

后续步骤