Firebase功能正在消失,没有任何解释或错误

68de4m5k  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(140)

我正在尝试使用Firebase Firestore和Firebase Cloud Functions来实现一个消息应用程序。
实质上,聊天消息作为单独的文档存储在子集合中。一开始,我实现了直接从客户端添加文档,监听集合并在发生更改时更新客户端,但后来我决定切换到使用云函数,以便我可以添加一些在服务器端更好地完成的功能(过滤等)。
因此,我创建了一个用于发送消息的函数,当用户从应用程序调用该函数时,该函数代表用户创建文档(即点击发送按钮)。
该功能工作,我能够通过日志监控进程。不幸的是,函数开始消失,没有错误,控制台报告函数已成功执行,执行时间通常不到一秒钟。
我怀疑这与可能会继续运行的promises有关,但这是相同的代码,今天工作,但失败了。
如果我再尝试几次,功能似乎又能工作了。我需要保持功能“温暖”吗?云计算功能是否不够可靠,无法处理此类任务?当我告诉我的用户消息已发送时,我需要能够确认消息已发送,并在失败时与用户进行沟通。
很难调试这个问题,因为没有抛出错误(甚至没有信息消息,就像没有发生一样),它只是说函数成功地完成了执行,没有发生任何事情。
我是不是漏掉了什么?谢谢大家。

exports.sendMessage = functions.https.onCall((data, context) => {
  if (context.auth.uid == undefined) {
    console.warn("SEND MESSAGE: USER NOT SIGNED IN");
    return;
  }

  console.log("Sending message:", data)
  const matchId = data["matchId"];
  const message = data["message"]
  const uid = context.auth.uid

  admin.firestore().collection(MatchingUsers).doc(matchId).collection(UserMessages).add({
    type: "text",
    from: uid,
    message: message,
    timestamp: admin.firestore.Timestamp.now()
  }).then(result => {
    console.log("Message sent")
  }).catch(err => {
    console.log("Error sending mesage:", err)
  })
})
klr1opcd

klr1opcd1#

如HTTP Callable Cloud Functions文档中所述:
若要在异步操作后返回数据,请返回promise。
下面是一个例子:

const sanitizedMessage = sanitizer.sanitizeText(text); // Sanitize the message.
return admin.database().ref('/messages').push({
  text: sanitizedMessage,
  author: { uid, name, picture, email },
}).then(() => {
  console.log('New Message written');
  // Returning the sanitized message to the client.
  return { text: sanitizedMessage };
})

所以你需要调整你的代码如下:

exports.sendMessage = functions.https.onCall((data, context) => {
  if (context.auth.uid == undefined) {
    console.warn("SEND MESSAGE: USER NOT SIGNED IN");
    //Here send back an error as explained here: https://firebase.google.com/docs/functions/callable#handle_errors
  }

  console.log("Sending message:", data)
  const matchId = data["matchId"];
  const message = data["message"]
  const uid = context.auth.uid

  //Note the return on next line
  return admin.firestore().collection(MatchingUsers).doc(matchId).collection(UserMessages).add({
    type: "text",
    from: uid,
    message: message,
    timestamp: admin.firestore.Timestamp.now()
  }).then(result => {
    console.log("Message sent");
    return { text: "Message sent" };
  }).catch(err => {
    console.log("Error sending mesage:", err);
    //Here, again, send back an error as explained here: https://firebase.google.com/docs/functions/callable#handle_errors
  })
})

如果您不想向客户端返回值,您可以如下操作,当add()异步方法返回的Promise解析时返回null。(没有测试,但它应该工作)。

exports.sendMessage = functions.https.onCall((data, context) => {
  if (context.auth.uid == undefined) {
    console.warn("SEND MESSAGE: USER NOT SIGNED IN");
    return null;
  }

  console.log("Sending message:", data)
  const matchId = data["matchId"];
  const message = data["message"]
  const uid = context.auth.uid

  //Note the return on next line
  return admin.firestore().collection(MatchingUsers).doc(matchId).collection(UserMessages).add({
    type: "text",
    from: uid,
    message: message,
    timestamp: admin.firestore.Timestamp.now()
  }).then(result => {
    console.log("Message sent");   //Actually, if you don't need this console.log() you can remove this entire then() block, returning the promise from add() is enough
    return null;
  }).catch(err => {
    console.log("Error sending mesage:", err);
    return null;
  })
})

相关问题