Firebase 实时数据库模拟器

实时数据库模拟器旨在让您更轻松地编写单元测试,以便检查数据库安全规则的行为。

原则上讲,您可以针对本地模拟器(而不是生产数据库)运行整个应用,但可能会遇到一些问题。具体来讲,与 Firebase 身份验证的集成会中断。我们正在努力在这方面进行完善,但目前我们建议您尝试编写一些测试,确保您的安全规则符合您的预期。

当模拟器启动时,系统将出于安全角度的考虑而“锁定”(".read"".write" 均为 false)您的数据库。在编写之前,您必须设置安全规则。您可以使用测试 SDK 模块直接在单元测试框架内部执行此操作(参见下文)。

和往常一样,我们衷心期待您的反馈。如果您有任何想法,请告知我们!

模拟器和生产数据库的区别

  1. 您不必明确地创建数据库实例。模拟器会自动创建数据库实例供访问。
  2. 每个新数据库在启动时都使用封闭规则,因此非管理员用户将无法执行读取或写入操作。
  3. 任何数据库都将接受字符串 "owner" 作为管理员身份验证令牌。
    1. 如果您想使用 REST API 作为管理员,请添加标头
      Authorization: Bearer owner
    2. 您可以通过此方法使用 curl 设置规则。假设您的规则位于 database.rules.json 文件中,则具体设置将如下所示:
      curl -X PUT -H 'Authorization: Bearer owner' --data @database.rules.json http://localhost:9000/.settings/rules.json?ns=<name>
  4. 数据库模拟器不会与其他 Firebase 产品进行有效互动。值得注意的是,标准的 Firebase 身份验证流程将无法进行。不过,我们在测试模块中提供了 initializeTestApp() 方法,该方接受 auth 字段。使用此方法创建的 Firebase 手柄的行为就好像它已作为您提供的任何实体成功通过了身份验证一样。如果您传入 null,它的行为将与未经过身份验证的用户相同(例如,auth != null 规则将失败)。

安装模拟器

要安装实时数据库模拟器,请使用 Firebase CLI 并按照以下步骤操作。

  1. 要安装实时数据库模拟器,请执行以下操作:firebase setup:emulators:database
  2. 使用以下命令启动模拟器。模拟器将在您进行各项测试时运行。 firebase serve --only database

与模拟器进行互动

普通的 Firebase 实时数据库实例可通过 firebaseio.com 的子域名访问,并且您可以访问如下所示的 REST API:

https://<database_name>.firebaseio.com/path/to/my/data.json

模拟器在本地运行,并可通过 localhost:9000 访问。要与特定数据库实例互动,您必须使用查询参数指定数据库名称。

http://localhost:9000/path/to/my/data.json?ns=<database_name>

我们提供了 @firebase/testing 模块,以便让您更轻松地使用 Firebase SDK 与模拟器互动。通过使用 @firebase/testing 模块,您可以与实时数据库模拟器的本地运行的版本进行互动。如果您遇到超时或 ECONNREFUSED 错误,请仔细检查模拟器是否正在运行。

我们强烈建议使用最新版本的 Node.js,以便您能够使用 async/await 表示法。几乎所有您可能希望测试的行为都涉及异步函数,而测试模块可与基于 Promise 的代码搭配使用。

该模块提供了以下方法:

initializeTestApp({ databaseName: , auth: }) => FirebaseApp

使用此方法可创建以特定用户身份通过了身份验证的应用,以用于测试。

此方法会返回一个初始化的 Firebase 应用,该应用与选项中指定的数据库名称和 auth 变量替换值相对应。请注意,此方法不使用 databaseURL,因为它的运行不需要远程服务器。

firebase.initializeTestApp({
  databaseName: "my-database",
  auth: { uid: "alice" }
});

initializeAdminApp({ databaseName: }) => FirebaseApp

使用此方法可创建以管理员身份通过了身份验证的应用以设置测试状态。

此方法会返回一个初始化的 Firebase 管理应用,该应用与选项中指定的数据库名称相对应。在从数据库读取数据和向数据库写入数据时,该应用会绕过安全规则。

firebase.initializeAdminApp({ databaseName: "my-database" });

loadDatabaseRules({ databaseName: , rules: }) => Promise

使用此方法可设置数据库的规则。

此方法可以将规则发送到本地运行的数据库。您需要采用将“databaseName”和“rules”指定为字符串的选项对象。

firebase
      .loadDatabaseRules({
        databaseName: "my-database",
        rules: "{'rules': {'.read': false, '.write': false}}"
      });

apps() => [FirebaseApp]

返回目前已初始化的所有测试应用和管理应用。

使用此方法可在各次测试之间或测试之后清理应用(请注意,具有处于活动状态的侦听器的已初始化应用可防止 JavaScript 退出):

 Promise.all(firebase.apps().map(app => app.delete()))

assertFails(pr: Promise) => Promise

返回一个在输入成功时遭拒并在输入遭拒时成功的 promise。

使用此方法可声明数据库读取或写入失败:

firebase.assertFails(app.database().ref("secret").once("value"));

assertSucceeds(pr: Promise) => Promise

返回一个在输入成功时成功并在输入遭拒时遭拒的 promise。

使用此方法可声明数据库读取或写入成功:

firebase.assertSucceeds(app.database().ref("public").once("value"));

生成测试报告

运行一系列测试后,您可以访问测试范围报告,报告中显示了每个安全规则的评估方式。要获取此类报告,请在模拟器运行时查询其上的公开端点。对于适合浏览器的版本,请使用以下网址:

http://localhost:9000/.inspect/coverage?ns=<database_name>

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

http://localhost:9000/.inspect/coverage.json?ns=<database_name>

快速入门

如果您只是想获取一个最基本的有效示例,请尝试使用 JavaScript 快速入门

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面