我通过Firebase Functions使用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,
})
始终必须以response.status(200).send()
或response.status(200).end()
结束HTTP函数。在上面的函数中,您有response.status(200)
,因此必须以response.status(200).send()
或response.status(200).end()
结束它。如果有帮助,请查看文档。