Firebase-functions: Getting strange errors on app deleted and ECONNRESET

Created on 22 Mar 2017  路  9Comments  路  Source: firebase/firebase-functions

Version info

firebase-functions: 0.5.2
firebase-tools: 3.5.0
firebase-admin: 4.1.3

Test case

Unsure of the test case as it seems to be caused by an ECONNRESET on firebase functions. However it may be caused by me returning promises incorrectly.

Steps to reproduce

I'm writing a progress percentage to the events ref, as my job progresses, with a function:

function progress(percentage) {
    return event.data.adminRef.child('_progress').set(percentage)
}

I'm hitting a strange ECONNRESET error and and an app error seen below.
It's only happening on one of my functions repeatedly, and I'm thinking it might be how I'm returning the promise here. When I call the progress(10) percentage throughout my function, is it enough to do something like this:

...
function progress(percentage) {
    return event.data.adminRef.child('_progress').set(percentage)
}
progress(10);
...

Will that keep my firebase-function running or do I also have to return the function?
return progress(10);

Could that be whats causing the below strange intermittent errors?

Were you able to successfully deploy your functions?

Yes

Actual behavior

FIREBASE WARNING: {"code":"app/invalid-credential","message":"Credential implementation provided to initializeApp() via the \"credential\" property failed to fetch a valid Google OAuth2 access token with the following error: \"read ECONNRESET\"."}

And

Error: Firebase app named "__admin__" has already been deleted.
at FirebaseAppError.Error (native)
at FirebaseAppError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:25:28)
at new FirebaseAppError (/user_code/node_modules/firebase-admin/lib/utils/error.js:70:23)
at FirebaseApp.checkDestroyed_ (/user_code/node_modules/firebase-admin/lib/firebase-app.js:249:19)
at FirebaseApp.getService_ (/user_code/node_modules/firebase-admin/lib/firebase-app.js:232:14)
at DeltaSnapshot.get [as adminRef] (/user_code/node_modules/firebase-functions/lib/providers/database.js:146:48)
at progress (/user_code/new_order.js:16:30)
at Promise.all.then.result (/user_code/new_order.js:56:17)
at process._tickDomainCallback (internal/process/next_tick.js:129:7)

Most helpful comment

@tsaarikivi Are you aware any asynchronous tasks need to be returned in order to keep a firebase-function alive? https://firebase.google.com/docs/functions/terminate-functions

I believe the ECONNRESET was being caused by my function terminating before my asynchronous functions were actually finished.

e.g: What not to do

//Example of what NOT to do
exports.lineItem = functions.database.ref('/carts/{userId}').onWrite(event => {
    admin.database().ref('somewhereElse').set({success: true});
});

e.g: What should be done (Notice the return)

//Example of returning the asynch/promise
exports.lineItem = functions.database.ref('/carts/{userId}').onWrite(event => {
    return admin.database().ref('somewhereElse').set({success: true});
});

I had been doing this in all my functions, but in one specific function I was using another function passing a callback, and had confused myself with my returns.
Best way to test is (if you're doing anything asynchronously):

  1. add a few console.logs() within the asynchronous call
  2. Check your firebase-function logs
  3. Click the three dots at the end of one of the console outputs to 'View all from this execution'
    screen shot 2017-03-22 at 11 49 28
  1. Verify that all logs are between the start and finish logs for the execution
  2. If you've got logs after the function's completion log, you're probably not returning your promises correctly 馃憤

All 9 comments

I think I'm going to try return the function and wrap things in Promise.all() like I do with everything else. I'll leave this open as I'm not sure this was causing the two errors, but it's probably not coincidence they were happening on only one of my functions.

Fixing up my promise/task returns seems to have fixed it. I can see others on slack functions channel talking about ECONNRESET issues, perhaps they're stuff is running beyond the function shutdown also? I'll mention my issue in there and see 馃憣

@ahaverty
I'm sorry, what exactly do you mean by fixing promise/task returns? Could you post a how to not and how to difference. I think this might be the issue for me too!

@tsaarikivi Are you aware any asynchronous tasks need to be returned in order to keep a firebase-function alive? https://firebase.google.com/docs/functions/terminate-functions

I believe the ECONNRESET was being caused by my function terminating before my asynchronous functions were actually finished.

e.g: What not to do

//Example of what NOT to do
exports.lineItem = functions.database.ref('/carts/{userId}').onWrite(event => {
    admin.database().ref('somewhereElse').set({success: true});
});

e.g: What should be done (Notice the return)

//Example of returning the asynch/promise
exports.lineItem = functions.database.ref('/carts/{userId}').onWrite(event => {
    return admin.database().ref('somewhereElse').set({success: true});
});

I had been doing this in all my functions, but in one specific function I was using another function passing a callback, and had confused myself with my returns.
Best way to test is (if you're doing anything asynchronously):

  1. add a few console.logs() within the asynchronous call
  2. Check your firebase-function logs
  3. Click the three dots at the end of one of the console outputs to 'View all from this execution'
    screen shot 2017-03-22 at 11 49 28
  1. Verify that all logs are between the start and finish logs for the execution
  2. If you've got logs after the function's completion log, you're probably not returning your promises correctly 馃憤

Weird, I actually do return promises so probably not that. But I'll have to recheck my code.

Interested to hear if it solves it for you too, let me know 馃憣

Hey @ahaverty you're absolutely right! I'm glad you were able to figure this out. Having your functions pre-maturely return also explains the log line "Firebase app named "admin" has already been deleted." The SDK deletes apps after the function's return promise resolves in order to prevent concurrency leaks. So when your function doesn't return the promise, but returns undefined, the app gets deleted before the 'set' operation executes. So it cannot successfully execute.

I'm closing this issue now since it's been resolved.

Thanks @laurenzlong If firebase functions is capable of logging something that late, It might be nice to suggest that late promises is the cause. Looks like a few people's issues this week were caused by them not returning promises properly, I know it's explained a few of mine. Thanks for looking 馃榿馃憣

That's a good suggestion! I'll file that ticket internally. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ArbestNew picture ArbestNew  路  5Comments

h36ahmed picture h36ahmed  路  5Comments

jspri picture jspri  路  5Comments

piuccio picture piuccio  路  4Comments

adrielwerlich picture adrielwerlich  路  4Comments