【问题标题】:Firebase Function:Function returned undefined, expected Promise or valueFirebase 函数:函数返回未定义、预期的 Promise 或值
【发布时间】:2018-12-05 16:38:30
【问题描述】:

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

我总是收到这个错误(不管它是否工作):

Function returned undefined, expected Promise or value

这是我的like函数的代码:

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


});

我不明白我哪里出错了。请帮忙!

【问题讨论】:

  • 一些观察。 1)您的代码很难按照此处的格式进行操作。 2) 您使用的是真正旧版本的 firebase-functions SDK - 考虑升级到最新的 1.x 版本并将您的代码迁移到新的 API。
  • 嘿,对于破旧的格式感到抱歉。我在编辑中对其进行了改进。
  • 我不认为你有所有的代码。上次你打电话给 Promise.all。
  • 是的,我错过了。这是现在的整个代码。请仔细查看

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


【解决方案1】:

您在以下情况下返回未定义:

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

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

【讨论】:

  • 如果 event.data.exists() 返回 false 或 ownerUid == userUid 发生,则不会发送通知。这里的问题是通知已发送,然后我收到错误 Function returned undefined, expected Promise or value。我已经编辑了问题中的代码,现在也包含了一个负责 sendToDevice().then() 的 Promise4,但它仍然不起作用。
  • 但在这些情况下,您的函数将返回未定义,并且您会看到您抱怨的消息。改为返回 null 或承诺。关键是您需要确保在代码的每个分支中都返回了某些内容,而不仅仅是主要的成功案例。
  • 按照你的建议,我在两种情况下都返回了 null 1) event.data.exists() 返回 false 和 2) ownerUid == userUid。我仍然遇到同样的错误。我的第一条评论是强调这样一个事实,即当我测试代码时,我确保成功案例发生,这反过来又给了我上述错误。
  • 我已经编辑了问题中的代码以反映更改。请仔细查看。
【解决方案2】:

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

【讨论】:

  • 您的回答帮助我得出了正确的答案。我不知道 promises.push 功能。您的函数返回一个 Promise 并且错误消失但未发送通知。无论如何,谢谢。
  • 很好,如果 device_token 是一个只使用一个令牌的字符串:promises.push(admin.messaging().sendToDevice(cO.val(), payload));
【解决方案3】:
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;
}

});

这段代码为我解决了问题!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 2019-08-06
    • 2018-12-03
    • 2019-11-03
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多