1

I've defined a Firebase cloud function that executes upon realtime database onCreate trigger. The function performs it's intended algorithm perfectly except that the logs always show the error: Function returned undefined, expected Promise or value. I've already tried so many things, but I still can't get that error to go away. The important snippets of the code is below.

I've already properly returned a promise. Any ideas how to make the error go away?

index.js

const sendNotificationMessageModule = require('./sendNotificationMessage');

exports.sendNotificationMessage = functions.database.ref( '/Notifications/{pushId}').onCreate((snapshot, context) => {
  sendNotificationMessageModule.sendNotificationMessage(snapshot, context, db, admin);
});

sendNotificationMessage.js

First parts of the code:

exports.sendNotificationMessage = function(snapshot, context, db, admin) {
.
.
.

Last parts of the code:

        if(...) {
        .
        .
        .
          var androidNode = {};
          androidNode[constants.propertyNotificationString] = notificationNode;
          message[constants.propertyAndroidString] = androidNode;

          return admin.messaging().send(message)
          .then((response) => {
            console.log('Successfully sent message:', response);
            return snapshotNotificationMessage.ref.remove();
          })
          .catch((error) => {
            console.log('Error sending message:', error);
          });
        }

As you can see, the message was successfully sent, but the error is still there. And of course, the data in the realtime database was also successfully removed.

cloud function error

2
  • 1
    When posting code, please post the entire function, not just the function body. It's very important to see what sort of cloud function it is. Commented Jun 24, 2018 at 16:48
  • Hi, I watched your videos! They are so helpful in understanding promises. I didn't post the entire code because it is so long! So I just posted the end part of it. The function is a realtime database trigger onCreate, it successfully executes the send message, but the functions still exits with the error above. I'm posting the first and last parts now. Commented Jun 25, 2018 at 5:26

2 Answers 2

2

Cloud Functions for Firebase triggered by events in the background must return a promise (or in certain cases a value, e.g. return false;).

Since admin.messaging().send() returns a promise (see doc), you just have to return this promise, as follows:

var androidNode = {};
androidNode[constants.propertyNotificationString] = notificationNode;
message[constants.propertyAndroidString] = androidNode;
....
return admin.messaging().send(message);
})
.catch((error) => {
    console.log('Error sending message:', error);
    return false;
});

However, you are also calling snapshotNotificationMessage.ref.remove();, which also returns a promise. Therefore you should chain these promises in your Cloud Function. This should probably be done as follows but without your full code it is difficult to guarantee that this is 100% correct. If you add to your question your entire code, we may adapt it.

....
    var androidNode = {};
    androidNode[constants.propertyNotificationString] = notificationNode;
    message[constants.propertyAndroidString] = androidNode;
    return snapshotNotificationMessage.ref.remove();
.then(() => {
    return admin.messaging().send(message);
})
.catch((error) => {
    console.log('Error sending message:', error);
    return false;
});

In addition, I suggest you watch these two videos from the Firebase team, which explain why and how to return a promise:

https://www.youtube.com/watch?v=7IkUgCLr5oA

https://www.youtube.com/watch?v=652XeeKNHSk

The first one is more about HTTP Functions that are triggered through an HTTP request (so not with a background event) while the second is focused on background event triggered Functions, but it is advised to watch the first one before watching the second one.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I'll test your suggested answers.. and watch the video. I'll get back to you if it works or not.
I watched the videos and they were very helpful, but I'm still getting the errors. -_-;
Please add to your Pots the entire Cloud Function code and not only snippets.
I modified my question and added the posts and screenshot of cloud function logs. Hope the modification makes my question clearer. Thanks!
1

You will return to return the promise returned by sendNotificationMessage. That's how Cloud Functions knows when all async work is done:

const sendNotificationMessageModule = require('./sendNotificationMessage');

exports.sendNotificationMessage = functions.database.ref( '/Notifications/{pushId}').onCreate((snapshot, context) => {
  return sendNotificationMessageModule.sendNotificationMessage(snapshot, context, db, admin);
});

5 Comments

Oh my, how did I overlook that?! But anyway, I added the return in the parent function, but the error still persists. >_<!!!
Well, since you havne't shown all the code, it's impossible to know for sure. Usually, on Stack Overflow, you provide a MCVE to help everyone be able to reproduce exactly the problem you're having. stackoverflow.com/help/mcve
I created a testFunction exports.testFunction = functions.database.ref('/test/{pushId}').onCreate((snapshot, context) => { return snapshot.ref.remove() .then(function() { console.log("successfully removed"); return true; }); }); and it doesn't return any errors. So I suspect the send function is not returning the promise properly.
But the code you're asking about isn't the same as what you just posted in the comment. Edit your question to include the minimal, complete code that exhibits the problem.
I'm so sorry for the comment above. You are right!!! I reviewed my entire code again, and I used once function in my database references, but I wasn't using promises in those, instead I just used the old callback methods. I converted everything to promises now, and it worked!!!! NO MORE ERRORS! But I need to refactor my code so I don't nest the promises. I also need to refactor it in such a way that promise chaining is sequential coz I need one promise to run after another. Thank you so much for your persistence!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.