我正在尝试使用Firebase Firestore和Firebase Cloud Functions实施消息传递应用程序。
从本质上讲,聊天消息作为单独的文档存储在子集合中。最初,我将其实现为直接从客户端添加文档,并在发生更改时侦听集合并更新客户端,但后来我决定切换到使用Cloud函数,以便可以添加一些更好在服务器上完成的功能侧面(过滤等)。
因此,我创建了一个用于发送消息的功能,当用户从应用程序调用该功能时(即,点击发送按钮),该功能将代表用户创建文档。
该功能正常工作,我能够通过日志监视过程。不幸的是,这些功能开始消失而没有错误,控制台报告该功能已成功执行,通常只需不到一秒钟即可执行。
我怀疑这与可能会继续执行的承诺有关,但是这与今天一直有效但失败的代码相同。
如果再尝试几次,这些功能似乎又能正常工作了。我需要保持功能“温暖”吗?云功能是否不够可靠,无法处理此类任务?当我向用户说一条消息已发送时,我需要能够确认该消息已发送,并在失败时与用户进行通信。
很难调试该问题,因为没有引发任何错误(甚至没有信息消息,就好像没有发生一样),它只是说该函数成功完成了执行并且什么也没发生。
我在这里错过了什么吗?谢谢。
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)
})
})
答案 0 :(得分:2)
如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
})
})
如果您不想将值返回给客户端,则可以执行以下操作,当null
异步方法返回的Promise解析后,返回add()
。 (未经测试,但应该可以使用。)
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;
})
})