2

I wanted to test a firestore rule. Below is firestore.rules. I wanted to check that these security rules are valid. Then I tried to use jest and firebase testing. However when executing "npm test", an error, "connect ECONNREFUSED 127.0.0.1:8080" occured.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /clubUsers/{uid} {
      allow read: if request.auth != null
        && request.auth.uid == uid;
      allow create: if request.auth != null
        && request.auth.uid == uid;   
      allow update: if request.auth != null
        && request.auth.uid == uid;  
    }
  }
}

And my test script is here.

const firebase = require('@firebase/testing/');
const fs = require('fs');

const project_id = "PROJECT ID";

describe("testing firestore rules", () => {

    beforeAll(
        async () => {
            await firebase.loadFirestoreRules({
                projectId: project_id,
                rules: fs.readFileSync('../../firestore.rules', 'utf8'),
            });
        }
    );

    afterEach(
        async () => {
            await firebase.clearFirestoreData({ projectId: project_id });
        }
    );

    afterAll(
        async () => {
            await Promise.all(
                firebase.apps().map((app) => app.delete())
            );
        }
    );

    function authedApp(auth) {
        return firebase.initializeTestApp({
            projectId: project_id,
            auth: auth,
        }).firestore();
    }

    describe("testing get and write", () => {

        test("testing get", async () => {
            const db = authedApp({ uid: 'UID' });
            const message = db.collection("clubUsers").doc("UID");
            await firebase.assertSucceeds(message.get());
        })

        test("testing write", async () => {
            const db = authedApp({ uid: "UID" });
            const message = db.collection("clubUsers").doc("UID");
            await firebase.assertSucceeds(
                message.set({ text: "hoge" })
            );
        })
    })

})

I tried the test while firebase emulator is opened.

I checked what is using port 8080 by executing sudo lsof -P -i:8080 on terminal. However, nothing has used port 8080.

Itsu
  • 21
  • 1

1 Answers1

3

Just ran into this too today... a couple of sources (GitHub and here) led to a solution. This is an issue with the call to firebase.clearFirestoreData() and occurs when the emulator can't be found on the default host:port it is expecting.

The solutions suggest setting an environment variable to define the host and port that works for your setup. For example:

process.env.FIRESTORE_EMULATOR_HOST = '127.0.0.1:5002';

You can find the correct host:port combination to use after you've fired up the emulators with firebase emulators:start

This has been addressed in the new modular v9 JS SDK, but does require a bit of refactoring to the new API (as defined in the docs). You can now specify the host and port when initialising:

testEnv = await initializeTestEnvironment({
    projectId: projectId,
    firestore: {
        host: '127.0.0.1',
        port: 5002,
    }
});

PS. Don't also be fooled like I was by assuming that 127.0.0.1 and localhost are always the same!

jt_uk
  • 1,362
  • 1
  • 15
  • 17
  • This answer was key for me. For anyone running Jest tests and running into this "connect ECONNREFUSED" error for me it was that I was not properly setting up and tearing down my tests: https://jestjs.io/docs/setup-teardown. As jt_uk mentions, calling firebase.clearFirestoreData() and it failing can cause this ECONNREFUSED error to occur. After I changed my beforeeach() setups to not include the firebase.clearFirestoreData() it works correctly. Be CAREFUL what you put inside your beforeEach() and afterEach() in your tests as the firestore instance might not have been instantiated yet. – Jeremy Bailey May 04 '23 at 19:52