FIRESTORE (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array

2,463

Solution 1

It seems to be a compatibility issue between the latest @firebase/[email protected] version and the internally used [email protected] version. I had the same error and got it working with a temporary workaround.

Try downgrading your @firebase/testing version to ^0.15.0. After a quick npm i it worked for me. You can still upgrade to latest versions later as soon as they fix the current compatibility issues.

I will update my answer as soon as this happens.

Update: This is the issue I created on the firebase-js-sdk GitHub page https://github.com/firebase/firebase-js-sdk/issues/3096.

Seems to be related to a bug in the testing framework Jest. The issue describes a workaround which does not require to downgrade.

I will update my answer as soon as the workaround is not required anymore.

Solution 2

Here's the Firebase issue:

Apparently it's caused by a bug in Jest ...

... that includes this workaround:

Steps to reproduce and fix ...

Solution 3

You can solve this problem simply by adding the following JSDOC comment to the top of your test file, which prevents Jest running your tests with JSDOM.

In spec/collections.spec.js:

/**
 * @jest-environment node
 */

describe("my rules", () => {
  // ...
});

The underlying issue is an incompatibility between jsdom and an internal assertion used by the firebase library, documented here: https://github.com/nodejs/node/issues/20978

The workaround noted by Tony O'Hagan (here) allows the tests to run in the JSDOM environment but the solution is pretty complex. If you're only testing Firestore security rules then you don't need JSDOM.

Update: Jest 27 (May 2021) changed Jest's default behavior to run in the Node environment instead of JSDOM

Share:
2,463
Blen
Author by

Blen

Updated on December 20, 2022

Comments

  • Blen
    Blen over 1 year

    My script keeps raising this error. The code I've written is for testing Firestore security rules. I basically wanted to test my firestore security while adding the javascript functions to it. It is possible to write the rules in firestore console and save them then and there but I wanted to use an IDE - VS code.

    I wanted to know how to fix "FIRESTORE (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array". I've updated my npm and also tried an answer I found on Github which said for me to install first "npm i jest-environment-uint8array". It did not work. I have also tried to use " TextEncoder" Like: var uint8array = new TextEncoder("utf-8").encode("Posts"); var string = new TextDecoder("utf-8").decode(uint8array); It did not work as well. I would really appreciate it if you guys answered me thoroughly since I am just a novice.

    My code for testing is

    const { setup, teardown } = require("./helpers");
    
    describe("General Safety Rules", () => {
      afterEach(async () => {
        await teardown();
      });
    
      test("should deny a read to the posts collection", async () => {
        const db = await setup();
        const postsRef = db.collection("Posts");
        await expect(postsRef.get()).toDeny();
      });
    
    });
    

    My helper js has basically the setup and the teardown for after when my code finishes.

    const firebase = require("@firebase/testing");
    const fs = require("fs");
    
    module.exports.setup = async (auth, data) => {
      const projectId = `rules-spec-${Date.now()}`;
    
      const app = firebase.initializeTestApp({
        projectId,
        auth
      });
    
      const db = app.firestore();
    
      // Apply the test rules so we can write documents
      await firebase.loadFirestoreRules({
        projectId,
        rules: fs.readFileSync("firestore-test.rules", "utf8")
      });
    
      // write mock documents if any
      if (data) {
        for (const key in data) {
          const ref = db.doc(key); // This means the key should point directly to a document
          await ref.set(data[key]);
        }
      }
    
      // Apply the actual rules for the project
      await firebase.loadFirestoreRules({
        projectId,
        rules: fs.readFileSync("firestore.rules", "utf8")
      });
    
      return db;
    };
    
    module.exports.teardown = async () => {
      // Delete all apps currently running in the firebase simulated environment
      Promise.all(firebase.apps().map(app => app.delete()));
    };
    

    The error is:

    jest ./spec

    (node:8200) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
     FAIL  spec/collections.spec.js (10.284 s)
      General Safety Rules
        × should deny a read to the posts collection (4598 ms)
        × should deny a write to users even when logged in (131 ms)
    
      ● General Safety Rules › should deny a read to the posts collection
    
        FIRESTORE (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array
    
          at fail (node_modules/@firebase/firestore/src/util/assert.ts:39:9)
          at hardAssert (node_modules/@firebase/firestore/src/util/assert.ts:53:5)
          at JsonProtoSerializer.fromBytes (node_modules/@firebase/firestore/src/remote/serializer.ts:250:7)
          at JsonProtoSerializer.fromWatchChange (node_modules/@firebase/firestore/src/remote/serializer.ts:431:32)
          at PersistentListenStream.onMessage (node_modules/@firebase/firestore/src/remote/persistent_stream.ts:568:41)
          at node_modules/@firebase/firestore/src/remote/persistent_stream.ts:448:21
          at node_modules/@firebase/firestore/src/remote/persistent_stream.ts:501:18
          at node_modules/@firebase/firestore/src/util/async_queue.ts:358:14
    
      ● General Safety Rules › should deny a write to users even when logged in
    
        FIRESTORE (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array
    
          at fail (node_modules/@firebase/firestore/src/util/assert.ts:39:9)
          at hardAssert (node_modules/@firebase/firestore/src/util/assert.ts:53:5)
          at JsonProtoSerializer.fromBytes (node_modules/@firebase/firestore/src/remote/serializer.ts:250:7)
          at JsonProtoSerializer.fromWatchChange (node_modules/@firebase/firestore/src/remote/serializer.ts:431:32)
          at PersistentListenStream.onMessage (node_modules/@firebase/firestore/src/remote/persistent_stream.ts:568:41)
          at node_modules/@firebase/firestore/src/remote/persistent_stream.ts:448:21
          at node_modules/@firebase/firestore/src/remote/persistent_stream.ts:501:18
          at node_modules/@firebase/firestore/src/util/async_queue.ts:358:14
    
      console.error
        [2020-05-20T13:13:11.851Z]  @firebase/firestore: Firestore (7.14.3): FIRESTORE (7.14.3) INTERNAL ASSERTION FAILED: value must be undefined or Uint8Array
    
          at Logger.defaultLogHandler [as _logHandler] (node_modules/@firebase/logger/src/logger.ts:115:57)
          at logError (node_modules/@firebase/firestore/src/util/log.ts:45:20)
          at fail (node_modules/@firebase/firestore/src/util/assert.ts:34:3)
          at hardAssert (node_modules/@firebase/firestore/src/util/assert.ts:53:5)
          at JsonProtoSerializer.fromBytes (node_modules/@firebase/firestore/src/remote/serializer.ts:250:7)
          at JsonProtoSerializer.fromWatchChange (node_modules/@firebase/firestore/src/remote/serializer.ts:431:32)
    
    Test Suites: 1 failed, 1 total
    Tests:       2 failed, 2 total
    Snapshots:   0 total
    Time:        18.711 s
    Ran all test suites matching /.\\spec/i.
    (node:8200) UnhandledPromiseRejectionWarning: FirebaseError: Caught error after test environment was torn down
    
    The client has already been terminated.
    (node:8200) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
    (node:8200) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
    Jest did not exit one second after the test run has completed.
    
    This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.