Firebase initialization error from Node.js in AWS Lambda

1,688 views
Skip to first unread message

Chris Pointon

unread,
Jul 19, 2016, 2:28:11 PM7/19/16
to Firebase Google Group
I have a Node.js Lambda function on AWS that accesses my Firebase DB via a service account. The function runs on a schedule.

I found that every other time the function was called, it would error out with 

Firebase App named '[DEFAULT]' already exists

It seems that Firebase is holding the initialized app between invocations of the function. 

I added the following check for firebase.apps.length before initializing and it seems to have resolved the problem.

if(firebase.apps.length == 0) {
firebase.initializeApp({
  serviceAccount: "auth.json",
databaseURL: config.firebaseURL
});
}

My question is - is this a sensible approach or am I storing up problems for myself later?

Kato Richardson

unread,
Jul 20, 2016, 12:20:46 PM7/20/16
to Firebase Google Group
Hi Chris,

This sounds strange. I would first believe that the code is somehow calling initializeApp() twice before I believed AWS is holding it between invocations.

You may wish to turn on debugging, try to simplify the scope, and see if you can find the source of the problem. I'm thinking it's likely in the code.

To directly answer your question, any time you directly depend on undocumented API features, you always run the risk of breakage--they can and do change without warning. With that in mind, if you're up for the risk, you should at least mitigate it as much as possible by doing the following:
  • Wrap any code accessing undocumented API features in a service or method, so that if it changes in the future, you only have one place in your code to mitigate. Remember that this may break in production; you don't want to be refactoring usages in your live code, so a single method to fix would be preferable.
  • Test everything before you use it and have a default behavior that doesn't blow up (e.g. instead of depending on `firebase.apps`, try something like:  `if( firebase.hasOwnProperty('apps') ) { /* proceed with checking the length */  } else { /* take some reasonable default action */ }`
  • Make sure you read the release notes carefully before upgrading.
  • Make sure you have a staging environment to test against before upgrading.
☼, Kato

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/99a68139-ffeb-4acc-99e0-54d4b48574cf%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Kato Richardson | Developer Programs Eng | kato...@google.com | 775-235-8398

Michael Bleigh

unread,
Jul 20, 2016, 12:27:24 PM7/20/16
to Firebase Google Group

Lambda probably keeps the same process running to avoid spin-up times for each invocation, and since firebase.initializeApp affects global state you’d run into this.

I’d try putting firebase.initializeApp() outside the actual handler function if you’re able to do so (I’m not super-experienced with Lambda). That ought to only execute on initialization of the process and avoid multiple instantiation.

Kato Richardson

unread,
Oct 19, 2016, 12:26:53 AM10/19/16
to Firebase Google Group

Hi Chris,

We’ve been bouncing this around and trying to decide if there’s something we could help with to reduce friction for Amazon developers. Did Michael’s advice help? Is it possible to put the initializeApp() into some sort of “on create” section so it’s not run with each invocation?

If not, another possibility might be to invoke it with a timestamp based name as the second argument:

var app = firebase.initializeApp({ ... }, 'instance-' + Date.now());
var ref = firebase.database(app).ref(...);

This is sub-optimal, as it creates a new JS instance in memory each time your event is invoked, but it’s pretty low overhead, so probably a decent workaround.

☼, Kato

On Wed, Jul 20, 2016 at 9:27 AM, ‘Michael Bleigh’ via Firebase Google Group [fireba...@googlegroups.com](mailto:fireba...@googlegroups.com) wrote:

Lambda probably keeps the same process running to avoid spin-up times for each invocation, and since firebase.initializeApp affects global state you’d run into this.

I’d try putting firebase.initializeApp() outside the actual handler function if you’re able to do so (I’m not super-experienced with Lambda). That ought to only execute on initialization of the process and avoid multiple instantiation.

On Wed, Jul 20, 2016 at 9:20 AM ‘Kato Richardson’ via Firebase Google Group [fireba...@googlegroups.com](mailto:firebase-talk@googlegroups.com) wrote:

Hi Chris,

This sounds strange. I would first believe that the code is somehow calling initializeApp() twice before I believed AWS is holding it between invocations.

You may wish to turn on debugging, try to simplify the scope, and see if you can find the source of the problem. I'm thinking it's likely in the code.

To directly answer your question, any time you directly depend on undocumented API features, you always run the risk of breakage--they can and do change without warning. With that in mind, if you're up for the risk, you should at least mitigate it as much as possible by doing the following:
  • Wrap any code accessing undocumented API features in a service or method, so that if it changes in the future, you only have one place in your code to mitigate. Remember that this may break in production; you don't want to be refactoring usages in your live code, so a single method to fix would be preferable.
  • Test everything before you use it and have a default behavior that doesn't blow up (e.g. instead of depending on `firebase.apps`, try something like:  `if( firebase.hasOwnProperty('apps') ) { /* proceed with checking the length */  } else { /* take some reasonable default action */ }`
  • Make sure you read the release notes carefully before upgrading.
  • Make sure you have a staging environment to test against before upgrading.
☼, Kato
On Tue, Jul 19, 2016 at 10:31 AM, Chris Pointon <ch...@projectx.fitness> wrote:
I have a Node.js Lambda function on AWS that accesses my Firebase DB via a service account. The function runs on a schedule.

I found that every other time the function was called, it would error out with 

Firebase App named '[DEFAULT]' already exists

It seems that Firebase is holding the initialized app between invocations of the function. 

I added the following check for firebase.apps.length before initializing and it seems to have resolved the problem.

if(firebase.apps.length == 0) {
firebase.initializeApp({
  serviceAccount: "auth.json",
databaseURL: config.firebaseURL
});
}

My question is - is this a sensible approach or am I storing up problems for myself later?

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-talk+unsubscribe@googlegroups.com.

To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/99a68139-ffeb-4acc-99e0-54d4b48574cf%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--

Kato Richardson | Developer Programs Eng | kato...@google.com | 775-235-8398

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-talk+unsubscribe@googlegroups.com.

To post to this group, send email to fireba...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-talk+unsubscribe@googlegroups.com.

To post to this group, send email to fireba...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Luke D

unread,
Oct 19, 2016, 8:25:39 PM10/19/16
to Firebase Google Group
Hi Chris,

My lambda function looks like this and does not give the duplicate app warning:

(function (exports) {
    'use strict';
    
    let firebase = require('firebase');

    firebase.initializeApp({
        serviceAccount: {},
       databaseURL: "https://theapp.firebaseio.com"
    });
   
    exports.handler = (event, context, callback) => {
        context.callbackWaitsForEmptyEventLoop = false;
        doFirebaseStuff()
            .then(() => {
                callback(null, true);
            }).catch((error) => {
                callback();
            });
    };
    
}(exports));

Thanks,
Luke

Kato Richardson

unread,
Oct 25, 2016, 4:33:21 PM10/25/16
to Firebase Google Group
Luke: Thanks for sharing! Great stuff.

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-talk+unsubscribe@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages