Skip to content

Firestore v10 Operations Hang Indefinitely in Jest JSDOM Environment #7808

@kaisermann

Description

@kaisermann

Operating System

MacOS Sonoma 14.1.1

Browser Version

n/a

Firebase SDK Version

10.6.0

Firebase SDK Product:

Firestore

Describe your project's tooling

For simplicity's sake, I just have some functions that are supposed to be used by our client-side apps (browser) that reads and writes from/to Firestore and I want to test them with jest and the firestore emulator.

So the only tooling necessary to reproduce is:

  • jest@29 for the testing
  • jest-environment-jsdom@29 for mocking the env as a browser
  • firebase-tools@12 for starting the firestore emulator

Describe the problem

When I set the testing environment to use jsdom, every read/write call to Firestore hangs indefinitely until the timeout is reached. There is no error message. If the testing environment is set to node, the calls work as expected.

For what it's worth, I'm refactoring my codebase from v8 to v10 and the testing environment was working as expected by doing the workaround described in this previous issue: #3096 (comment)

Repro Repository

I tried debugging this for a bit and cloned the js-SDK locally and linked with my project. The furthest that I manage to go is that the watchStream never responds, nor is the current online state set to Offline. It seems that when the env is set to JSDOM, the tracked online state is kept at Unknown. Which in turn causes the shouldRaiseInitialEvent to never be true. (I might have gotten this wrong, I'm new to the codebase).


FWIW, I did find some StackOverflow unanswered questions related to this behavior:

Sorry if this is unrelated to this codebase, feel free to close it if it's the case.

edit:

I found this comment on an old issue and adding useFetchStreams makes the issue go away, even though it's not documented and exposed in the typings anymore.

Steps and code to reproduce issue

With repro:

  1. Clone the repository: Repro Repository
  2. Install dependencies: npm install
  3. Run tests: npm emulate-and-test

Manually:

  1. Write a test suite connecting to the firestore emulator and read/write something from it:
const { initializeApp } = require("firebase/app");
const {
  connectFirestoreEmulator,
  doc,
  initializeFirestore,
  getDoc,
  setDoc,
} = require("firebase/firestore");

const testApp = initializeApp({
  apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  projectId: "some-project-id",
});

const testFirestore = initializeFirestore(testApp, {
  ignoreUndefinedProperties: true,
});

connectFirestoreEmulator(testFirestore, "127.0.0.1", 5001);

test("hangs forever", async () => {
  const ref = doc(testFirestore, "users", "alice");

  // hangs forever
  await setDoc(ref, { age: 29 });

  // would also hang forever
  console.log((await getDoc(ref)).data());

  expect(true).toBe(true);
});
  1. Configure jest to use jsdom as the testing environment:
/** @type {import('jest').Config} */
module.exports = {
  // If the following line is commented, the repro test passes
  // If the following line is uncommented, the repro test hangs forever
  testEnvironment: 'jest-environment-jsdom',
};
  1. Run the emulator and tests: firebase emulators:exec --only firestore \"jest\"

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions