You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firestore规则测试持续超时的问题排查求助

测试Firestore安全规则时的超时问题排查与解决

问题背景

测试自定义Firestore安全规则时,运行测试用例会触发超时错误;延长Jest超时时间后测试能通过,但仍会出现Firestore客户端无法连接后端的错误日志,不符合预期。

环境与配置

1. Firestore模拟器启动

通过以下命令启动模拟器,启动状态正常,Firestore模拟器地址为127.0.0.1:8080,可通过浏览器访问:

❯ npm run firebase:run:emulator

> warzywniax@0.0.0 firebase:run:emulator
> cd firebase && firebase emulators:start --project=warzywniax --import=./seed --export-on-exit

i  emulators: Starting emulators: auth, firestore, storage
i  firestore: Importing data from /firebase/seed/firestore_export/firestore_export.overall_export_metadata
i  firestore: Firestore Emulator logging to firestore-debug.log
✔  firestore: Firestore Emulator UI websocket is running on 9150.
i  auth: Importing config from /firebase/seed/auth_export/config.json
i  auth: Importing accounts from /firebase/seed/auth_export/accounts.json
i  ui: Emulator UI logging to ui-debug.log

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://127.0.0.1:4000/               │
└─────────────────────────────────────────────────────────────┘

┌────────────────┬────────────────┬─────────────────────────────────┐
│ Emulator       │ Host:Port      │ View in Emulator UI             │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Authentication │ 127.0.0.1:9099 │ http://127.0.0.1:4000/auth      │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Firestore      │ 127.0.0.1:8080 │ http://127.0.0.1:4000/firestore │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Storage        │ 127.0.0.1:9199 │ http://127.0.0.1:4000/storage   │
└────────────────┴────────────────┴─────────────────────────────────┘
  Emulator Hub running at 127.0.0.1:4400
  Other reserved ports: 4500, 9150

2. Jest初始化脚本

在setupFilesAfterEnv钩子中初始化测试环境:

import { initializeTestEnvironment, RulesTestEnvironment } from '@firebase/rules-unit-testing';
import firebase from 'firebase/compat/';

export let testEnvironment: RulesTestEnvironment;
export let guestUserContext: firebase.firestore.Firestore;
beforeAll(async () => {
  testEnvironment = await initializeTestEnvironment({
    firestore: {
      host: '127.0.0.1',
      port: 8080,
    },
    projectId: 'warzywniax',
  });
  guestUserContext = testEnvironment.unauthenticatedContext().firestore();
  console.info('TEST_ENV is ready:\n', testEnvironment);
  console.info('GUEST_USER is ready:\n', guestUserContext);
});

3. 测试用例

运行的简单测试用例:

import { assertSucceeds } from '@firebase/rules-unit-testing';
import { guestUserContext } from '../integration-setup';

describe('Offers collection tests', () => {
  it('should allow to read offers for any user', async () => {
    const testQuery = guestUserContext.collection('offers');

    expect(await assertSucceeds(testQuery.get()));
  });
});

错误现象

  1. 初始运行测试时触发Jest超时:
FAIL  test/integration/firebase/firestore.rules.spec.ts (5.234 s)
  Offers collection tests
    ✕ should allow to read offers for any user (5001 ms)

  ● Offers collection tests › should allow to read offers for any user

    thrown: "Exceeded timeout of 5000 ms for a test.
    Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout.
  1. 延长超时至30秒(--testTimeout=30000)后,测试通过但出现Firestore连接错误日志:
console.error
    [2023-03-30T15:45:44.552Z]  @firebase/firestore: Firestore (9.17.1): Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.
    This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.

      at Logger.defaultLogHandler [as _logHandler] (node_modules/@firebase/logger/src/logger.ts:115:57)
      at Logger.Object.<anonymous>.Logger.error (node_modules/@firebase/logger/src/logger.ts:210:5)
      at x (node_modules/@firebase/firestore/dist/index.esm2017.js:124:11)
      at Pu.au (node_modules/@firebase/firestore/dist/index.esm2017.js:13778:20)
      at nc.op (node_modules/@firebase/firestore/dist/index.esm2017.js:13748:14)
      at node_modules/@firebase/firestore/dist/index.esm2017.js:14307:14
      at node_modules/@firebase/firestore/dist/index.esm2017.js:17414:73
      at node_modules/@firebase/firestore/dist/index.esm2017.js:17447:54

PASS  test/integration/firebase/firestore.rules.spec.ts (10.335 s)
  Offers collection tests
    ✓ should allow to read offers for any user (10168 ms)

可能原因与解决方案

1. 客户端默认尝试SSL连接模拟器

Firestore客户端默认启用SSL连接,但本地模拟器仅提供HTTP服务,导致连接协商延迟甚至失败。

解决方案:在初始化TestEnvironment时,显式添加ssl: false配置:

testEnvironment = await initializeTestEnvironment({
  firestore: {
    host: '127.0.0.1',
    port: 8080,
    ssl: false, // 禁用SSL,适配模拟器的HTTP服务
  },
  projectId: 'warzywniax',
});

2. WebSocket连接适配问题

Firestore客户端默认优先使用WebSocket连接,部分环境下WebSocket与模拟器的兼容性不佳,导致连接超时。

解决方案:添加experimentalForceLongPolling: true配置,强制使用长轮询:

testEnvironment = await initializeTestEnvironment({
  firestore: {
    host: '127.0.0.1',
    port: 8080,
    ssl: false,
    experimentalForceLongPolling: true, // 强制长轮询
  },
  projectId: 'warzywniax',
});

3. 测试环境未正确清理

测试结束后未关闭Firestore连接,残留的连接状态或离线缓存影响下一次测试,导致连接延迟。

解决方案:添加afterAll钩子清理测试环境:

afterAll(async () => {
  await testEnvironment.cleanup();
});

修改后的完整初始化脚本

import { initializeTestEnvironment, RulesTestEnvironment } from '@firebase/rules-unit-testing';
import firebase from 'firebase/compat/';

export let testEnvironment: RulesTestEnvironment;
export let guestUserContext: firebase.firestore.Firestore;

beforeAll(async () => {
  testEnvironment = await initializeTestEnvironment({
    firestore: {
      host: '127.0.0.1',
      port: 8080,
      ssl: false,
      experimentalForceLongPolling: true,
    },
    projectId: 'warzywniax',
  });
  guestUserContext = testEnvironment.unauthenticatedContext().firestore();
});

afterAll(async () => {
  await testEnvironment.cleanup();
});

内容的提问来源于stack exchange,提问作者Krzysztof Kaczyński

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:14:58