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

Error: The default Firebase app does not exist #6

Closed
btrautmann opened this issue Apr 5, 2018 · 16 comments
Closed

Error: The default Firebase app does not exist #6

btrautmann opened this issue Apr 5, 2018 · 16 comments

Comments

@btrautmann
Copy link

btrautmann commented Apr 5, 2018

Version info

firebase-functions-test: 0.1.1

firebase-functions: ^1.0.0

firebase-admin: ~5.11.0

Test case

In index.js I have:

admin.initializeApp(functions.config().firebase);

Thus in test.js I have:

before(() => {
  // Trying to mock the config
  test.mockConfig({ firebase: 'FakeFirebaseConfig' });
  adminInitStub = sinon.stub(admin, 'initializeApp');
  myFunctions = require('../index');
});

Steps to reproduce

Attempt to write a Firestore test that uses the above before() and uses makeDocumentSnapshot(), like:

  describe('updateActiveNotesCount', () => {
    // Test Case: Setting environments/{environment}/users/{userId}/people/{personId}/notes/{noteId}/isActive to 'true' should cause
    // .../{personId}/activeNotesCount to be incremented
    it('Should increment active notes count on the person field', () => {
      // Make snapshot for state of database beforehand
      const beforeSnap = test.firestore.makeDocumentSnapshot({isActive: false}, 'environments/dev/users/1/people/2/notes/3');
      // Make snapshot for state of database after the change
      const afterSnap = test.firestore.makeDocumentSnapshot({isActive: true}, 'environments/dev/users/1/people/2/notes/3');
      const change = test.makeChange(beforeSnap, afterSnap);
      // Call wrapped function with the Change object
      const wrapped = test.wrap(myFunctions.updateActiveNotesCount);
      wrapped(change);
      // Assert envinonments/dev/users/1 has `activeNotesCount` of 1
      return assert(true); // Not sure how to make this assertion yet, but doesn't matter
    })
  });

Expected behavior

Test should run (and fail due to bad assertion) without any errors caused by SDK

Actual behavior

Error: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services. at FirebaseAppError.Error (native) at FirebaseAppError.FirebaseError [as constructor] (node_modules/firebase-admin/lib/utils/error.js:39:28) at FirebaseAppError.PrefixedFirebaseError [as constructor] (node_modules/firebase-admin/lib/utils/error.js:85:28) at new FirebaseAppError (node_modules/firebase-admin/lib/utils/error.js:119:28) at FirebaseNamespaceInternals.app (node_modules/firebase-admin/lib/firebase-namespace.js:105:19) at FirebaseNamespace.app (node_modules/firebase-admin/lib/firebase-namespace.js:372:30) at FirebaseNamespace.ensureApp (node_modules/firebase-admin/lib/firebase-namespace.js:388:24) at FirebaseNamespace.fn (node_modules/firebase-admin/lib/firebase-namespace.js:328:30) at Object.makeDocumentSnapshot (node_modules/firebase-functions-test/lib/providers/firestore.js:44:45) at Context.it (test/test.js:45:41)

The relevant code within test.js at line 45 is:

const beforeSnap = test.firestore.makeDocumentSnapshot({isActive: false}, 'environments/dev/users/1/people/2/notes/3');

The relevant code within firestore.js at line 44 is:

else {
    firestoreService = firebase_admin_1.firestore(app_1.testApp().getApp()); // Line 44
    project = process.env.GCLOUD_PROJECT;
}

Update: I suspected that firestore() on admin needs to be mocked so I added:

firestoreStub = sinon.stub(admin, 'firestore');

but get the error:

TypeError: Attempted to wrap undefined property firestore as function
@abraham
Copy link

abraham commented Apr 8, 2018

I'm having a similar issue.

@ahaverty
Copy link

ahaverty commented Apr 9, 2018

The initializeApp call has changed from admin.initializeApp(functions.config().firebase); to this admin.initializeApp();
I'd start looking there if the error is related to initializeApp.
Their online docs go into detail on when to import certain things.

@btrautmann
Copy link
Author

Interesting, thanks @ahaverty. Last I checked the config was still listed as the correct way to inject your env variables like Slack webhook URL, for instance (See here).

@ahaverty
Copy link

@btrautmann
Copy link
Author

Thanks @ahaverty I'll check out the migration stuff and hopefully that resolves this issue!

@NickFranceschina
Copy link

NickFranceschina commented May 8, 2018

I'm running into this also. It is happening because admin.firestore() needs to return an interface that is wrapping the firebase app and it looks for the "default app" which doesn't exist because we stubbed admin.initializeApp() which does nothing, of course... so firebase admin is never initialized and there are no apps setup (not even [DEFAULT]) @btrautmann probably saw the TypeError because .firestore() isn't a function but a property getter... See dude's answer to this on SO:

https://stackoverflow.com/questions/48139037/cannot-mock-admin-firestore-during-unit-tests

Note his extra comment on the answer:

The remaining things in my scenario were still over 100 lines of mock code of firestore
functions because my cloud function would read various documents and then create
various documents in a transaction, mocking the entire nested promises with different
return values with chai etc was a pain in the nether regions.

Surely we're not all supposed to be mocking the entire .firestore() interface ourselves... but I don't see any examples around database related testing, so I'm not sure how to setup the data ahead of time?

@roykolak
Copy link

roykolak commented May 9, 2018

I don't understand this either. Especially since there is an 'online' testing mode that should be able to hit real the firestore api. But in my testing when I reference the firebase-admin package in a firestore function, I get The default Firebase app does not exist...

@alvico
Copy link

alvico commented May 17, 2018

Hitting the same wall >.<

@roykolak
Copy link

@alvico I solved my issue. I had my functions in separate files and each file did not include a call to admin.initializeApp(); at the top. When I add a call to admin.initializeApp(); at the top, my tests pass.

When I served my functions locally tho, it bombed out because an app can only be initialized once. Therefore, I updated the initializeApp line at the top of each of my function files to be this:

try {
  admin.initializeApp();
} catch (e) {}

@nelsonlarocca
Copy link

try {
admin.initializeApp();
} catch (e) {}

is it the best / correct way to address that or just a fix in the meanwhile ?

@kirjai
Copy link

kirjai commented May 26, 2019

Here's an alternative fix that worked for me:
In the main file, which exports the functions, the order of imports matters

// index.ts file
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);

// the rest of my imports go here
import ...

That way, if any of the files that i'm importing after the app initialization rely on the default firebase app (like if they initialize the firestore for example), the default app should already be set.

I'm using Typescript though, so unsure whether this would work the same way in JS

@AnushangaWimalasena
Copy link

This might sound like crazy, But I had the same issue. Then I've changed my "admin.initializeApp();" place like below. Then it works.

//
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const app = express();
//put here.
admin.initializeApp();

const db = admin.firestore();

const firebaseConfig = {
// config data
};

const firebase = require('firebase');

firebase.initializeApp(firebaseConfig);

@mahafuz
Copy link

mahafuz commented Feb 26, 2020

This might sound like crazy, But I had the same issue. Then I've changed my "admin.initializeApp();" place like below. Then it works.

//
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const app = express();
//put here.
admin.initializeApp();

const db = admin.firestore();

const firebaseConfig = {
// config data
};

const firebase = require('firebase');

firebase.initializeApp(firebaseConfig);

It did work for me, Thank you ❤️

@relair
Copy link

relair commented Jun 15, 2020

I had the same issue as the OP. All the responses so far seem to be referring to completely different issues which have nothing to do with testing.
If someone finds this issue again the way to deal with it is to stub the get method:

firestoreStub = sinon.stub(admin, 'firestore')
  .get(function () {
    return function () {
      return "data";
    }
  });

It is also similar for other parts such as auth, so if you are going to use offline mode you need to make sure you mock everything.

@CharlieOxendine
Copy link

I am encountering the same problem and have tried everything above with no luck. At first I had issues with sinon, so I assumed it has something to do with having to stub out .initializeApp() in our test file. But even after getting that to work by manually installing npm sinon, I still received this error.

@NealEhardt
Copy link

NealEhardt commented Nov 28, 2020

Thank you @relair ! Using your stub, I was able to get past the error. I was able to write offline unit tests without modifying the source file.

Here's my full firestore mock, which allows simple operations like db.collection('dogs').doc('fido').get().exists and db.collection('dogs').doc('fido').set(...)--

docStub = sinon.stub().returns({
  get: () => ({
    exists: false
  }),
  set: sinon.stub()
});
firestoreStub = sinon.stub(admin, 'firestore')
  .get(() => (() => ({
    collection: () => ({
      doc: docStub
    })
  })));

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

No branches or pull requests