Firebase cloud function - returned undefined,expected Promise or value

此生再无相见时 提交于 2019-12-31 05:47:07

问题


I'm trying to send a notification to a user but for some reason i have an error. The error is "Function returned undefined, expected Promise or value".

I cant understand what does this line means, hope you guys can take a look at my code and tell me where im wrong.

CODE

exports.sendNotification = functions.database.ref('/likes/{videoId}/{currentUser}').onWrite(event =>{
  console.log("Start send like notification");
  const model = event.data.val();
  let ownerVideoUserId = model.userVideoID;
  let username = model.userName;

  if(username == ""){
    username = "Somebody";
  }

  console.log("model notifi: ",model);
  console.log("userVideoID notifi: ",ownerVideoUserId);
  console.log("username notifi: ",username);

  let reference = admin.database().ref("/users/" + ownerVideoUserId);
        reference.once('value').then(snap => {
            //get the token
    let token = snap.child('token').val();
    console.log("user token: ",token);


  const payload = {
    data: {
      title: "Talent",
      message: username + " liked your video",
    }
  }

  return admin.messaging().sendToDevice(token,payload).then(function(res){
    console.log("Successfully sent message:", res);

  }).catch(function(error) {
    console.log("Error sending message:", error);
    });

   })
});

Can you spot my mistake?

EDIT exports.sendCommentNotification = functions.database.ref('genresComments/{genre}/{videoId}/{userId}').onWrite(event =>{ console.log("Start send comment notification"); const model = event.data.val(); let ownerVideoUserId = model.ownerVideoID; let username = model.userName;

    if(username == "")
      username = "Somebody";


    console.log("model: ",model);
    console.log("userVideoID: ",ownerVideoUserId);
    console.log("username: ",username);

      let reference = admin.database().ref("/users/" + ownerVideoUserId);
    return reference.once('value').then(snap => {
      //get the token
      let token = snap.child('token').val();
      console.log("user token: ",token);


    const payload = {
      data: {
        title: "Talent",
        message: username + " comment your post",
      }
    }

    return admin.messaging().sendToDevice(token,payload).then(function(res){
      console.log("Successfully sent message:", res);

    }).catch(function(error) {
      console.log("Error sending message:", error);
      });

   }).catch(function(error){
     console.log("Error with the reference:",error);

   }).then(()=>{
    console.log('notification');
  });
 });

回答1:


As you will see in the three videos from Doug Stevenson about "JavaScript Promises" from the Firebase video series (https://firebase.google.com/docs/functions/video-series/) you MUST return a Promise or a value in your Cloud Function, to indicate to the platform that it has completed.

So, in your case you may do as follows (if you don't care about the console logging):

exports.sendNotification = functions.database.ref('/likes/{videoId}/{currentUser}').onWrite(event =>{
  ....

  let reference = admin.database().ref("/users/" + ownerVideoUserId);
  return reference.once('value')
  .then(snap => {
     ...
     return admin.messaging().sendToDevice(token,payload);
  });
});

or as follows if you want to keep the console logging:

...
  let reference = admin.database().ref("/users/" + ownerVideoUserId);

  return reference.once('value')
  .then(snap => {
  return admin.messaging().sendToDevice(token,payload);
  .then(function(res){
    console.log("Successfully sent message:", res);
    return null;
  })
  .catch(function(error) {
    console.log("Error sending message:", error);
    return null;
  });
...



回答2:


As the error message hints, you aren't returning anything from the parent-level function... which is a problem for cloud functions. If you're going to be calling asynchronous code, like the ref.once('value') method, then you need to return that.

exports.sendNotification = functions.database.ref('/likes/{videoId}/{currentUser}').onWrite(event =>{
    console.log("Start send like notification");
    const model = event.data.val();
    let ownerVideoUserId = model.userVideoID;
    let username = model.userName;

    if(username == ""){
        username = "Somebody";
    }

    console.log("model notifi: ",model);
    console.log("userVideoID notifi: ",ownerVideoUserId);
    console.log("username notifi: ",username);

    let reference = admin.database().ref("/users/" + ownerVideoUserId);

    return reference.once('value').then(snap => {      // <----- RETURN NEEDED HERE
        //get the token
        let token = snap.child('token').val();
        console.log("user token: ",token);

        const payload = {
            data: {
                title: "Talent",
                message: username + " liked your video",
            }
        }

        return admin.messaging().sendToDevice(token,payload).then(function(res){
            console.log("Successfully sent message:", res);
        }).catch(function(error) {
            console.log("Error sending message:", error);
        });

    })
});

EDIT:

Definitely recommend you check out the video series Renaud recommends in his answer. Very good explanations in there.



来源:https://stackoverflow.com/questions/55186654/firebase-cloud-function-returned-undefined-expected-promise-or-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!