Firebase功能:函数返回的值未定义,预期的承诺或价值

时间:2018-06-26 21:34:55

标签: javascript firebase firebase-cloud-messaging google-cloud-functions

我编写了一个firebase函数来在我的android应用中发生类似事件时发送通知。通知功能在大多数情况下都很好用,但有时不起作用。

我总是收到此错误(无论它是否正常工作):

Function returned undefined, expected Promise or value

这是我喜欢的函数的代码:

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;
    } 


});

我不明白我要去哪里。请帮忙!

3 个答案:

答案 0 :(得分:1)

在以下情况下,您将返回未定义的值:

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

您还没有处理sendToDevice().then().catch()返回的承诺。该功能需要等到工作完成后才能终止。

答案 1 :(得分:1)

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;
}

});

此代码为我解决了问题!

答案 2 :(得分:0)

请测试以下更改,并告知我,我也建议更新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;
  });