Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@firebase/rules-unit-testing stalls on dbRef.set() with package.json settings jest.preset:"jest-expo" but succeeds with jest.preset:"ts-jest" #8708

Open
DrStoop opened this issue Jan 16, 2025 · 5 comments

Comments

@DrStoop
Copy link

DrStoop commented Jan 16, 2025

Operating System

Linux 6.8 Ubuntu 24.04.1 LTS 24.04.1 LTS (Noble Numbat)

Environment (if applicable)

Expo, React Native

Firebase SDK Version

@firebase/[email protected]

Firebase SDK Product(s)

Database

Project Tooling

React-Native app managed with Expo for Android & iOS:

Minimal reproducible example

https://github.com/DrStoop/expoWithJestFirebaseDatabaseEmulator.git

Detailed Problem Description

Minimal reproducible example

https://github.com/DrStoop/expoWithJestFirebaseDatabaseEmulator.git

What platform(s) does this occur on?

Jest testing environment with jest-expo preset

Summary

jest-expo preset causes dbRef.set() to stall when testing database rules with @firebase/rules-unit-testing

I am using firebase realtime database in my expo app and am writing database rules unit tests using @firebase/rules-unit-testing and the firebase emulator locally. I encountered the issue that the command await assertSucceeds(dbRef.set(5)); in __tests__/firebaseRealtimeDatabaseRules.test.ts stalls (infinitely) in my test. I created a minimal reproducible example and could nail the cause of the stalling down to the jest.preset: "jest-expo" in package.json. The test passes without stalling when setting it to jest.preset: "ts-jest" and it throws a timeout fail when set to jest.preset:"jest-expo" (also with increases timeouts):

 FAIL  __tests__/firebaseRealtimeDatabaseRules.test.ts (5.539 s)
  Can read write
    ✕  should succeed (5012 ms)

  ● Can read write ›  should succeed

    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."

      41 |   });
      42 |
    > 43 |   it(` should succeed`, async () => {
         |   ^
      44 |     const dbRef = database.ref(`authed`);
      45 |     // const unauthedRef = unauthedUser.database().ref(`unauthed`);
      46 |     const valueChange = dbRef.on("value", (snapshot) => {

      at it (__tests__/firebaseRealtimeDatabaseRules.test.ts:43:3)
      at Object.describe (__tests__/firebaseRealtimeDatabaseRules.test.ts:15:1)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        5.881 s

I'm running the firebase database emulator with initial command:

$ firebase emulators:start --only database --project database


i  emulators: Starting emulators: database
i  database: Database Emulator logging to database-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            │
├──────────┼────────────────┼────────────────────────────────┤
│ Database │ 127.0.0.1:9000 │ http://127.0.0.1:4000/database │
└──────────┴────────────────┴────────────────────────────────┘
  Emulator Hub running at 127.0.0.1:4400
  Other reserved ports: 4500

Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.

jest-expo preset

  • The test script initially connects to the database emulator via localhost:9000 and initializes the database rules.
  • The dbRef.set(value) method does not send the value itself to the database and the database does not set any values, see emulator debug log:
[2025-01-09T17:39:59.546Z] 19:39:59.546 [NamespaceSystem-blocking-namespace-operation-dispatcher-9] INFO com.firebase.core.namespace.StateManager - Namespace database-default-rtdb status Active to Active
 {"metadata":{"emulator":{"name":"database"},"message":"19:39:59.546 [NamespaceSystem-blocking-namespace-operation-dispatcher-9] INFO com.firebase.core.namespace.StateManager - Namespace database-default-rtdb status Active to Active\n"}}
  • Also dbRef.set() methods show the same issue.

ts-jest preset

  • The test script also connects tot the database emulator, updates the database rules and successfully sends the value with dbRef.set(value), see database debug log:
[2025-01-09T18:09:53.068Z] 20:09:53.067 [NamespaceSystem-blocking-namespace-operation-dispatcher-10] INFO com.firebase.core.namespace.StateManager - Namespace database-default-rtdb status Active to Active
 {"metadata":{"emulator":{"name":"database"},"message":"20:09:53.067 [NamespaceSystem-blocking-namespace-operation-dispatcher-10] INFO com.firebase.core.namespace.StateManager - Namespace database-default-rtdb status Active to Active\n"}}
[2025-01-09T18:09:53.098Z] 20:09:53.098 [FirebaseWorkerPool-1-2] WARN com.firebase.server.forge.App$ - Received service account token eyJh...fX0., assuming ownership.
 {"metadata":{"emulator":{"name":"database"},"message":"20:09:53.098 [FirebaseWorkerPool-1-2] WARN com.firebase.server.forge.App$ - Received service account token eyJh...fX0., assuming ownership.\n"}}
  • The database emulator receives the value (5) and displays it in the UI:
    image

Question

Why is the jest preset "jest-expo" interfering with @firebase/rules-unit-testing and how can it be fixed? Or am I just missing something? Changing the preset to "ts-jest" is not an option unless I would run database rules unit tests in isolation in a separate project (which is also not really an option).

Thanks in advance!

Note

As this seems like a bug in the interface between an Expo preset jest-expo and the firebase emulator, I posted this issue already in the expo repository, but without getting feedback. So I'm hoping to get some hints from the firebase community here, THX!

Environment

expo-env-info 1.2.1 environment info:
    System:
      OS: Linux 6.8 Ubuntu 24.04.1 LTS 24.04.1 LTS (Noble Numbat)
      Shell: 5.2.21 - /bin/bash
    Binaries:
      Node: 20.13.0 - ~/.nvm/versions/node/v20.13.0/bin/node
      Yarn: 1.22.22 - ~/.nvm/versions/node/v20.13.0/bin/yarn
      npm: 10.9.0 - ~/.nvm/versions/node/v20.13.0/bin/npm
    npmPackages:
      expo: ~52.0.24 => 52.0.24 
      expo-router: ~4.0.16 => 4.0.16 
      react: 18.3.1 => 18.3.1 
      react-dom: 18.3.1 => 18.3.1 
      react-native: 0.76.5 => 0.76.5 
      react-native-web: ~0.19.13 => 0.19.13 
    npmGlobalPackages:
      eas-cli: 13.3.0
    Expo Workflow: managed

Expo Doctor Diagnostics

Enabled experimental React Native Directory checks. Unset the EXPO_DOCTOR_ENABLE_DIRECTORY_CHECK environment variable to disable this check.
✔ Check package.json for common issues
✔ Check Expo config for common issues
✔ Check native tooling versions
✔ Check if the project meets version requirements for submission to app stores
✔ Check for common project setup issues
✔ Check dependencies for packages that should not be installed directly
✔ Check for app config fields that may not be synced in a non-CNG project
✔ Check for issues with Metro config
✔ Check npm/ yarn versions
✔ Validate packages against React Native Directory package metadata
✔ Check Expo config (app.json/ app.config.js) schema
✔ Check for legacy global CLI installed locally
✔ Check that native modules do not use incompatible support packages
✔ Check that packages match versions required by installed Expo SDK
✔ Check that native modules use compatible support package versions for installed Expo SDK

Didn't find any issues with the project!

Steps and code to reproduce issue

Minimal reproducible example

https://github.com/DrStoop/expoWithJestFirebaseDatabaseEmulator.git

Steps

  • Install the project with npm install
  • Install firebase emulator
  • Run firebase realtime database emulator with firebase emulators:start --only database --project database
  • Run the test with npm run test will fail as this issue describes due to the {"jest":{"preset": "jest-expo"}}
  • Change the preset to {"jest":{"preset": "ts-jest"}} and kill & re-run the test with npm run test and the test will succeed without errors because it's not relying on jest-expo preset anymore
@DrStoop DrStoop added new A new issue that hasn't be categoirzed as question, bug or feature request question labels Jan 16, 2025
@google-oss-bot
Copy link
Contributor

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@jbalidiong jbalidiong added api: database needs-attention testing-sdk testing with emulator and removed needs-triage new A new issue that hasn't be categoirzed as question, bug or feature request labels Jan 16, 2025
@dlarocque
Copy link
Contributor

Hey @DrStoop, we'd be glad to investigate whether this is an issue with our SDK. Since we are not familiar with jest-expo, it is challenging for us to pinpoint which environment changes it makes cause this issue. If this issue could be narrowed down to a specific environment setting, it would really help us confirm whether we can do something to fix this on our end.

@DrStoop
Copy link
Author

DrStoop commented Jan 21, 2025

Hi @dlarocque, thanks for getting back to me. I get your point, that's why I also raised this issue in the expo repository first - unfortunately without response so far. I will be working on this problem and update you on the results if the issue is on the firebase or expo side. Thanks for now!

@hsubox76
Copy link
Contributor

Just to be clear, the information we'd need to pinpoint if this is a Firebase issue or not is basically "what does the jest-expo preset do?" Which may be an easier answer to get than presenting the entire bug to the Expo team and asking them to look into it as a whole. I went into the Expo repo trying to find out if it was a simple JSON config "extend" but it seems a bit more complicated than that (https://github.com/expo/expo/tree/main/packages/jest-expo) as there's a lot of code that eventually leads to the final jest config somewhere. If someone could quickly give a TLDR of how the jest-expo preset differs from ts-jest (or some other preset that works for you), that would really increase the odds of finding out what's going wrong.

@DrStoop
Copy link
Author

DrStoop commented Jan 23, 2025

Thanks @hsubox76 for looking into the issue. That's a good point comparing ts-jest with jest-expo to figure out which differences could cause the problem. After a quick look, ts-jest might not help reducing the "region of interest" though as ts-jest "simply" converts ts-files into js-files, whereas jest-expo seems to do a lot of mocking and adjusting environment configs to simulate react-native/mobile envs instead of node.js... at least that's my rough idea. So the problem could still be anywhere. My best guess right now is that a function or module that @firebase/rules-unit-testing depends on is being mocked by jest-expo, specifically a function or module that the dbRef.set() function is using. But I have tried jest.unmocking & jest.requireAcutaling all kind of modules, but without success so far. If I'm right the issue is on the jest-expo side. I will update you on any progress. thx again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants