firebase / firebase-functions-test

MIT License
232 stars 48 forks source link

Error: The default Firebase app already exists when running test with --watch #88

Closed oveddan closed 3 years ago

oveddan commented 3 years ago

I'm trying to find the example code, and running tests with typescript using:

"mocha \"**/*.test.ts\" --config .mocharc.json

with a .mocharc.json file:

{
    "require": "ts-node/register",
    "watch-files": ["./src/**/*.ts"] 
}

I'm following the instructions in the readme to use functionsTest:

import * as admin from "firebase-admin";
import * as functionsTest from "firebase-functions-test";
const communicationUrl = "https://{my-project}.firebaseio.com";
export const test = functionsTest({
    databaseURL: 'some-db'url',
    credential: admin.credential.applicationDefault(),
    projectId: 'some-project-id'
});

admin.initializeApp({
    credential: admin.credential.applicationDefault(),
    databaseURL: communicationUrl,
})

I add a basic test like:

describe('do something', () => {
    it('does something', async () => {
        const someData = {a: '5'};

       await admin.firestore().collection('someCollection').doc('someId').set(someData);

       // do some assertion that fails.
    });
})

When I save the file, and it re-runs the test again, I get an error:

" UnhandledPromiseRejectionWarning: Error: The default Firebase app already exists. This means you called initializeApp() more than once without providing an app name as the second argument. In most cases you only need to call initializeApp() once. But if you do want to initialize multiple apps, pass a second argument to initializeApp() to give each app a unique name."

If I start the test suite again, but delete initializeApp line - I get an error: Error: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.

It's not really well documented - do you need to call initializeApp even if you call functionsTest ? What happens in the watch case?

I wish there was an example repo with full setup for how to test with watch.

fergardi commented 3 years ago

It happens to me as well. Any news from this one? @oveddan Could you fix it?

inlined commented 3 years ago

The firebase-functions-test code does not initialize the default app. It initializes an app called firebase-functions-test. You could hpyothetically use that app or you can initialize your own.

I'm not familiar with your watch configuration or how it's reloading files (I'm presuming it clears the require cache and reloads the files?). If you want to make your initializeApp idempotent you could hypothetically do something like:

try {
  // will throw if we need to initialize. Will succeed if we run this file again
  firebase.app();
} catch  {
  firebase.initializeApp(...);
}
inlined commented 3 years ago

After speaking with a colleague, they offered an alternative workaround:

if (firebase.apps.length === 0) {
  firebase.initializeApp(...);
}