在将您的应用程序连接到 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 配置,也没有实时资源。这些项目通常通过代码实验室或其他教程访问。 演示项目的项目 ID 具有 | 使用演示 Firebase 项目时,您的应用程序和代码仅与模拟器交互。如果您的应用程序尝试与未运行模拟器的资源进行交互,则该代码将失败。 |
我们建议您尽可能使用演示项目。好处包括:
- 设置更简单,因为您无需创建 Firebase 项目即可运行模拟器
- 更强的安全性,因为如果您的代码不小心调用了非模拟(生产)资源,就没有数据更改、使用和计费的机会
- 更好的离线支持,因为无需访问互联网即可下载您的 SDK 配置。
检测您的应用以与模拟器对话
Android、Apple 平台和 Web SDK
按如下方式设置您的应用内配置或测试类以与 Cloud Firestore 交互。
Kotlin+KTX
// 10.0.2.2 is the special IP address to connect to the 'localhost' of // the host computer from an Android emulator. val firestore = Firebase.firestore firestore.useEmulator("10.0.2.2", 8080) firestore.firestoreSettings = firestoreSettings { isPersistenceEnabled = false }
Java
// 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);
迅速
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 模拟器都在运行时,它们会自动协同工作。
管理员 SDK
设置FIRESTORE_EMULATOR_HOST
环境变量后,Firebase Admin SDK 会自动连接到 Cloud Firestore 模拟器:
export FIRESTORE_EMULATOR_HOST="localhost:8080"
如果您的代码在 Cloud Functions 模拟器中运行,您的项目 ID 和其他配置将在调用initalizeApp
时自动设置。
如果您希望您的 Admin SDK 代码连接到在另一个环境中运行的共享模拟器,您将需要指定您使用 Firebase CLI 设置的相同项目 ID 。您可以将项目 ID 直接传递给initializeApp
或设置GCLOUD_PROJECT
环境变量。
Node.js 管理 SDK
admin.initializeApp({ projectId: "your-project-id" });
环境变量
export GCLOUD_PROJECT="your-project-id"
在测试之间清除数据库
Production Firestore 不提供用于刷新数据库的平台 SDK 方法,但 Firestore 模拟器为您提供了一个专门用于此目的的 REST 端点,可以从测试框架设置/拆卸步骤、测试类或 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"
实施了这样的步骤后,您可以对测试进行排序并触发您的功能,并确信旧数据将在运行之间被清除,并且您正在使用新的基线测试配置。
导入导出数据
Firebase 模拟器的数据库和 Cloud Storage 允许您从正在运行的模拟器实例中导出数据。定义要在单元测试或持续集成工作流程中使用的基线数据集,然后将其导出以在团队之间共享。
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 UI 中可视化客户端请求,包括 Firebase 安全规则的评估跟踪。
打开Firestore > Requests选项卡以查看每个请求的详细评估序列。
可视化规则评估报告
当您将安全规则添加到您的原型时,您可以使用 Local Emulator Suite 调试工具对其进行调试。
运行一套测试后,您可以访问测试覆盖率报告,其中显示了如何评估每个安全规则。
要获取报告,请在模拟器运行时查询公开的端点。对于浏览器友好的版本,请使用以下 URL:
http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage.html
这会将您的规则分解为表达式和子表达式,您可以将鼠标悬停在它们上以获取更多信息,包括计算次数和返回值。对于此数据的原始 JSON 版本,请在查询中包含以下 URL:
http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage
此处,该报告的 HTML 版本突出显示了引发未定义和空值错误的评估:
Cloud Firestore 模拟器与生产环境有何不同
Cloud Firestore 模拟器试图忠实地复制生产服务的行为,但有一些明显的限制。
交易
模拟器目前没有实现生产中看到的所有事务行为。当您测试涉及对一个文档的多个并发写入的功能时,模拟器完成写入请求的速度可能很慢。在某些情况下,锁定最多可能需要 30 秒才能释放。如果需要,考虑相应地调整测试超时。
索引
模拟器不跟踪复合索引,而是执行任何有效的查询。请务必针对真实的 Cloud Firestore 实例测试您的应用,以确定您需要哪些索引。
限制
模拟器不会强制执行生产中强制执行的所有限制。例如,模拟器可能允许生产服务因太大而拒绝的事务。确保您熟悉记录在案的限制,并确保您设计的应用程序能够主动避免这些限制。
接下来是什么?
- 如需一组精选的视频和详细的操作示例,请关注Firebase Emulators Training Playlist 。
- 研究涉及安全规则测试和 Firebase 测试 SDK 的高级用例:测试安全规则 (Firestore) 。
- 由于触发函数是与 Cloud Firestore 的典型集成,因此请在本地运行函数中了解有关 Cloud Functions for Firebase 模拟器的更多信息。