【问题标题】:Writing tests against local firestore emulator using the admin SDK with no auth使用没有身份验证的 admin SDK 针对本地 Firestore 模拟器编写测试
【发布时间】:2026-01-01 07:45:01
【问题描述】:

编辑:本质上是 firebase-emulator 文档的问题。见讨论here


我正在尝试使用 nodejs 管理 SDK 直接访问在本地模拟器上运行的 Firestore 实例。最小的例子:

// test.js
const admin = require("firebase-admin"); // version 9.1.1
admin.firestore().collection('foo').add({ a: 1 });

然后只需$ node test.js 看看它是否有效。

我能找到的唯一文档是one sentence,它告诉我设置一个环境变量,所以我做了,如下所示:

$ FIRESTORE_EMULATOR_HOST='localhost:1003' node test.js

但我收到一条错误消息 Unable to detect a Project Id in the current environment. 但我 am 在我的文件库项目文件夹中。我错过了什么?我的最终目标是编写单元测试来测试我使用 firestore 的服务器代码。服务器在云函数上运行,目前我能够从可以成功读取/写入本地数据库的测试套件中触发该函数,但这对于编写测试来说太复杂了。

firebase.json:

{
  ...
  "emulators": {
    "ui": {
      "enabled": true,
      "port": 1000
    },
    "hosting": {
      "port": 1001
    },
    "functions": {
      "port": 1002
    },
    "firestore": {
      "port": 1003
    }
  }
}

(这4个端口我都试过了,都没有用)

【问题讨论】:

    标签: firebase google-cloud-firestore


    【解决方案1】:

    当使用命令firebase emulators:start 运行模拟器时,您将获得模拟功能的端口,例如:

     ───────────────────────────────────────────────────────────────────────┐
    │ ✔  All emulators ready! View status and logs at http://localhost:4000 │
    └───────────────────────────────────────────────────────────────────────┘
    ┌───────────┬────────────────┬─────────────────────────────────┐
    │ Emulator  │ Host:Port      │ View in Emulator UI             │
    ├───────────┼────────────────┼─────────────────────────────────┤
    │ Functions │ localhost:5001 │ http://localhost:4000/functions │
    ├───────────┼────────────────┼─────────────────────────────────┤
    │ Firestore │ localhost:3000 │ http://localhost:4000/firestore │
    └───────────┴────────────────┴─────────────────────────────────┘
      Other reserved ports: 4400, 4500
    Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.
    

    比使用我创建的最小示例的相同链接:

    const admin = require("firebase-admin"); // version 9.1.1
    admin.initializeApp();
    var db = admin.firestore();
    db.settings({
        host: "localhost:3000",
        ssl: false
    });
    admin.firestore().collection('foo').add({ a: 1 })
    .then( (r) => console.log("document added: ",r.path) )
    .catch( (e) => console.log("error: ",e) );
    

    请注意,必须使用initializeApp 方法创建第一个应用程序实例,然后设置模拟器的路径。但是我想还有很多其他方法可以做到这一点。如果成功,这将显示创建文档的路径。我没有使用任何额外的设置。

    【讨论】:

    • 我的还是不行。我怀疑我的设置与您不同,但似乎一切都相同。 1.如果你在你的工作代码中console.log(process.env.FIRESTORE_EMULATOR_HOST),输出是什么? 2. 如果您删除db.settings({...}) 部分并重试,您会收到什么错误消息?谢谢!
    • 另外,如果您在工作代码中console.log(process.env.GOOGLE_APPLICATION_CREDENTIALS),它是否会输出您之前设置的路径,即服务帐户凭据 json?
    • 我发现了我的问题:我需要在 db.settings({}) 中提供“projectID”。我不知道为什么没有它你的工作。你是在别处配置的吗?
    【解决方案2】:

    我的经验是 Firebase 模拟器喜欢被赋予一个虚拟项目 ID。我在我的项目中使用bunny 之类的东西,让它看起来很有趣。

    使用以下命令启动模拟器:

    $ firebase emulators:start --project=bunny --only auth,functions,firestore
    

    不过,现实要复杂得多。对于真实世界的示例,您可以查看http://github.com/akauppi/GroundLevel-firebase-es

    【讨论】:

    • 推荐使用真实的项目ID,除非你没有使用模拟器UI来可视化你的数据&&你没有从函数访问数据库。简而言之,函数和 Web UI 总是使用真实 id,因此它们会访问不同的 db 实例而不是 bunny。
    • @ZYinMD 能给个推荐的链接吗?
    • OP第一行的链接
    【解决方案3】:

    实际上,我同意@akauppi 的answer。这是来自 firebase emulators 文档的 sn-p:

    连接到身份验证模拟器时,您需要指定项目 ID。您可以将项目 ID 直接传递给 initializeApp 或设置 GCLOUD_PROJECT 环境变量。请注意,您不需要使用真实的 Firebase 项目 ID;身份验证模拟器将接受任何项目 ID。

    【讨论】: