Maverick7
Maverick7

Reputation: 1097

Firebase Function:Function returned undefined, expected Promise or value

I have written a firebase function to send notification whenever a like occurs in my android app. The notification functionality works good most of the times but sometimes does not work.

I receive this error always ( whether it is working or not):

Function returned undefined, expected Promise or value

Here's the code of my like function:

exports.sendactorLikeNotification = functions.database.ref('/Likes/{post_id}/{user_id}')
.onWrite(event => {


   if (event.data.exists()) 
    {

      const message = event.data.val();
      const userUid = event.params.user_id;

      const ownerUid = message.owner_id;
      console.log("Owner id", ownerUid);
      const userPic = message.thumb_image;
      const userName = message.name;
      const post_key = event.params.post_id;
      const timestamp = admin.database.ServerValue.TIMESTAMP;

      if(ownerUid == userUid){return null;}

      const Promise1= admin.database().ref(`/notifs/${ownerUid}`).push({
        thumb_image: userPic,
        name: userName,
        user_id: userUid,
        post_id: post_key,
        text: "liked your post",
        type: "Like",
        read: "false",
        time: timestamp
     });

      const Promise2=admin.database().ref(`/Users/${ownerUid}/device_token`).once('value');

      const Promise3= Promise2.then(function(snapshot) {
          const getrealDeviceTokensPromise = snapshot.val();
          console.log("Device Token", getrealDeviceTokensPromise);

          // Notification details.
          const payload = {
                            notification: {
                                              title: 'Appname',
                                              body:  userName + ' has liked your post.',
                                              icon: "default",
                                              sound: "default",
                                              click_action: "OPEN_ACTIVITY_1"
                                          }
                        };

          const Promise4= admin.messaging().sendToDevice(getrealDeviceTokensPromise, payload)
                   .then(function (response) {
                       console.log("Successfully sent message:", response);
                       return Promise.all([Promise1,Promise3,Promise4]);
                   })
                   .catch(function (error) {
                       console.log("Error sending message:", error);
                       return null;
                   });

      }, function(error) {
      // The Promise was rejected.
          console.error(error);
          return null;
      });

    }

    else
    {
      return null;
    } 


});

I don't understand where I am going wrong. Please help!

Upvotes: 4

Views: 5394

Answers (3)

Maverick7
Maverick7

Reputation: 1097

exports.sendactorLikeNotification = functions.database.ref('/Likes/{post_id}/{user_id}').onWrite(event => {
  if (event.data.exists()) {

  const promises=[];



  const message = event.data.val();
  const userUid = event.params.user_id;

  const ownerUid = message.owner_id;
  console.log("Owner id", ownerUid);
  const userPic = message.thumb_image;
  const userName = message.name;
  const post_key = event.params.post_id;
  const timestamp = admin.database.ServerValue.TIMESTAMP;

  if(ownerUid == userUid){return null;}

    const a1=admin.database().ref(`/notifs/${ownerUid}`).push({
    thumb_image: userPic,
    name: userName,
    user_id: userUid,
    post_id: post_key,
    text: "liked your post",
    type: "Like",
    read: "false",
    time: timestamp
 });

  promises.push(a1);




   const a2= admin.database().ref(`/Users/${ownerUid}/device_token`).once('value').then(function(snapshot) {






      const getrealDeviceTokensPromise = snapshot.val();

      console.log("Device Token", getrealDeviceTokensPromise);

      // Notification details.
      const payload = {
        notification: {
          title: 'Appname',
          body:  userName + ' has liked your post.',
          icon: "default",
          sound: "default",
          click_action: "OPEN_ACTIVITY_1"
        }
      };

      const a3=admin.messaging().sendToDevice(getrealDeviceTokensPromise, payload)
               .then(function (response) {
                   console.log("Successfully sent message:", response);
               })
               .catch(function (error) {
                   console.log("Error sending message:", error);
               });


               promises.push(a3);


  }, function(error) {

      console.error(error);
  });
   promises.push(a1);
  return Promise.all(promises);

}

else
{
  return null;
}

});

This code solved the problem for me!

Upvotes: 2

Diego P
Diego P

Reputation: 1758

Please test the following changes and let me know, also I recommend updating the firebase-functions SDK:

exports.sendactorLikeNotification = functions.database.ref('/Likes/{post_id}/{user_id}')
  .onWrite(event => {
    if (event.data.exists()) {
      const promises = [];
      const message = event.data.val();
      const userUid = event.params.user_id;
      const ownerUid = message.owner_id;
      const userPic = message.thumb_image;
      const userName = message.name;
      const post_key = event.params.post_id;
      const timestamp = admin.database.ServerValue.TIMESTAMP;
      if (ownerUid === userUid) return null;
      return Promise.all([admin.database().ref(`/Users/${ownerUid}/device_token`).once('value')]).then(r => {
        const cO = r[0];
        const aP = admin.database().ref(`/notifs/${ownerUid}`).push({
          thumb_image: userPic,
          name: userName,
          user_id: userUid,
          post_id: post_key,
          text: "liked your post",
          type: "Like",
          read: "false",
          time: timestamp
        });
        promises.push(aP);
        const payload = {
          notification: {
            title: 'Appname',
            body: userName + ' has liked your post.',
            icon: "default",
            sound: "default",
            click_action: "OPEN_ACTIVITY_1"
          }
        };
        const tokensList = Object.keys(cO.val());
        promises.push(admin.messaging().sendToDevice(tokensList, payload));
        return Promise.all(promises);
      });
    }
    return null;
  });

Upvotes: 0

Doug Stevenson
Doug Stevenson

Reputation: 317467

You're returning undefined when:

  1. event.data.exists() returns false
  2. ownerUid == userUid

You're also not dealing with the promise returned by sendToDevice().then().catch(). The function needs to wait until that work is done before terminating.

Upvotes: 1

Related Questions