【发布时间】:2021-12-02 12:07:26
【问题描述】:
我正在通过 Firebase 函数使用 FCM 发送推送消息。消息正在正确发送,但在发送消息后我收到408 time-out 错误。我怀疑这可能与未清理的未注册令牌有关,因为:
- 如果我要向同一设备发送另一条消息,则会发生相同的超时,并且
- 我从 Firebase 日志中得到的唯一错误消息是
Function execution took 60002 ms, finished with status: 'timeout'。
exports.sendMessage = functions.https.onRequest(async (request, response) => {
const {
sender,
recipient,
content,
docID
} = request.body
functions.logger.log(
"docID:",
docID,
);
// Get the list of device notification tokens.
let deviceTokens; let ref;
try {
ref = admin.firestore().collection("deviceToken").doc(recipient);
const doc = await ref.get();
if (!doc.exists) {
console.log("No such document!");
response.status(500).send(e)
} else {
console.log("doc.data():", doc.data());
deviceTokens = doc.data().token;
}
} catch (e) {
response.status(500).send(e)
}
let senderProfile;
try {
senderProfile = await admin.auth().getUser(sender);
console.log("senderProfile", senderProfile);
} catch (e) {
console.log(e);
response.status(500).send(e)
}
// Notification details.
let payload = {
notification: {
title: senderProfile.displayName,
body: content,
sound: "default",
},
data: {
uid: senderProfile.uid,
displayName: senderProfile.displayName,
docID,
messageType: "status"
}
};
functions.logger.log(
"deviceTokens", deviceTokens,
"payload", payload,
);
// Send notifications to all tokens.
const messageResponse = await admin.messaging().sendToDevice(deviceTokens, payload);
// For each message check if there was an error.
messageResponse.results.forEach((result, index) => {
const error = result.error;
if (error) {
functions.logger.error(
"Failure sending notification to",
deviceTokens[index],
error,
);
// Cleanup the tokens who are not registered anymore.
if (error.code === "messaging/invalid-registration-token" ||
error.code === "messaging/registration-token-not-registered") {
const updatedTokens = deviceTokens.filter((token) => token !== deviceTokens[index]);
console.log("updatedTokens", updatedTokens);
ref.update({
token: updatedTokens,
})
.catch(function(e) {
console.error("Error removing tokens", e);
response.status(500).send(e)
});
}
}
});
response.status(200)
});
我不确定为什么以下内容没有清理未注册的令牌:
const updatedTokens = deviceTokens.filter((token) => token !== deviceTokens[index]);
ref.update({
token: updatedTokens,
})
【问题讨论】:
-
在上面提到的sn-p中你有
response.status(200)。您总是必须以response.status(200).send()或response.status(200).end()结束它。请查看following doc if it helps you.。 -
@RajeevTirumalasetty 谢谢。这仅适用于
functions.https.onRequest,对吧?functions.firestore.document()等其他 Firebase 函数不提供request和response。
标签: javascript firebase google-cloud-functions firebase-cloud-messaging