我的数据库如下
我的云功能是
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();
exports.userGotNewMessage = functions
.region(`europe-west1`)
.database
.ref(`user-messages/{userId}/{senderId}/{messageId}`)
.onCreate((snap, context) => {
var userId = context.params.userId
console.log(`Step 1 ${userId}`)
var text = snap.val().text
var toId = snap.val().toId
var numberOfUnreadMessages = 0
var db = admin.database()
if (userId === toId) {
console.log(`Step 2 ${userId}`)
var unreadMessagesRef = db.ref(`unread-messages/${userId}`)
unreadMessagesRef.on("value", (snap) => {
snap.forEach((childNode) => {
var nodeNumber = childNode.val().numberOfUnreadMessages
numberOfUnreadMessages = numberOfUnreadMessages + nodeNumber
})
return console.log(`Found ${numberOfUnreadMessages} unread messages for ${userId}`)
});
console.log(`Step 3 ${userId}`)
var token = 'dxfAkmce.....my testing device'
console.log(text)
var message = {
"token": String(token),
"data": {
"count": `${numberOfUnreadMessages}`
}
}
admin.messaging().send(message)
.then((response) => {
console.log(`Step 4 ${userId}`)
// Response is a message ID string.
return console.log('Successfully sent message:', response);
// detailed information about result if send succeded but something went wrong
// console.log(response.results[0].error);
})
.catch((error) => {
return console.log('Error sending message:', error);
});
}
console.log(`Step 5 ${userId}`)
return null
});
试图使用此功能会出现奇怪的行为。发送消息后计数未读消息的数量,还有更多,例如,启动后我从无处获得有关已计数未读消息的消息(数据库中根本没有16条消息)) 在控制台中这样的事情
3:05:23.627 PM userGotNewMessage成功发送消息: 项目/ chatapp-2e320 / messages / 1544015123460374
3:05:23.626 PM userGotNewMessage步骤4 VobaLy7AKMeYnGv7OgIokaeQ5UG2
3:05:23.340 PM userGotNewMessage函数执行耗时9毫秒, 状态为“ ok”
3:05:23.334 PM userGotNewMessage步骤5 nx9XfqgIqyS8PdZ8PzLQ9sEyKoV2
3:05:23.333 PM userGotNewMessage步骤1 nx9XfqgIqyS8PdZ8PzLQ9sEyKoV2
3:05:23.331 PM userGotNewMessage函数开始执行
3:05:23.325 PM userGotNewMessage函数执行耗时151毫秒, 状态为“ ok”
3:05:23.317 PM userGotNewMessage步骤5 VobaLy7AKMeYnGv7OgIokaeQ5UG2
3:05:23.317 PM userGotNewMessage再次问好
3:05:23.317 PM userGotNewMessage步骤3 VobaLy7AKMeYnGv7OgIokaeQ5UG2
3:05:23.317 PM userGotNewMessage找到1条未读消息 VobaLy7AKMeYnGv7OgIokaeQ5UG2
3:05:23.234 PM userGotNewMessage步骤2 VobaLy7AKMeYnGv7OgIokaeQ5UG2
3:05:23.234 PM userGotNewMessage步骤1 VobaLy7AKMeYnGv7OgIokaeQ5UG2
3:05:23.182 PM userGotNewMessage找到了16条未读消息 VobaLy7AKMeYnGv7OgIokaeQ5UG2
3:05:23.175 PM userGotNewMessage函数开始执行
我知道这是异步工作引起的,但是我不能自己解决它,因为我是一个完整的初学者。请帮助我修复此错误!
答案 0 :(得分:1)
正如@rijin在他的回答中所说,您应该返回异步send()
方法返回的promise。但是,同样重要,您不应该在Cloud Function的末尾返回null
。
通过返回null
(这将在send()
返回的承诺解决之前发生),您正在向Cloud Function指示工作已完成。因此,换句话说,Cloud Function在 异步作业完成之前停止执行。
此外,在Cloud Function(具有相对“短”寿命)中使用on()
侦听器实际上还不够。您最好使用once()
方法。
最后,您显然在Cloud Function中实现了两个不同的业务逻辑部分,一个部分用于报告许多未读消息,另一部分用于发送消息。您应该在两个不同的Cloud Functions中执行此操作,或者链接由异步方法(即once()
和send()
方法)返回的不同的Promise。
因此,对于消息发送部分,应执行以下操作:
exports.userGotNewMessage = functions
.region(`europe-west1`)
.database
.ref(`user-messages/{userId}/{senderId}/{messageId}`)
.onCreate((snap, context) => {
var userId = context.params.userId
console.log(`Step 1 ${userId}`)
var text = snap.val().text
var toId = snap.val().toId
var numberOfUnreadMessages = 0
var db = admin.database()
console.log(`Step 3 ${userId}`)
var token = 'dxfAkmce.....my testing device'
console.log(text)
var message = {
"token": String(token),
"data": {
"count": `${numberOfUnreadMessages}`
}
}
return admin.messaging().send(message);
});
如果您要将send()
和once()
方法链接到一个Cloud Function中,则可以按照以下步骤进行操作:
return admin.messaging().send(message)
.then(messageID => {
if (userId === toId) {
var unreadMessagesRef = db.ref(`unread-messages/${userId}`);
return unreadMessagesRef.once('value')
.then(snap => {
snap.forEach(childNode => {
var nodeNumber = childNode.val().numberOfUnreadMessages;
numberOfUnreadMessages = numberOfUnreadMessages + nodeNumber;
});
console.log(`Found ${numberOfUnreadMessages} unread messages for ${userId}`);
return null;
});
} else {
return null;
}
});
答案 1 :(得分:0)
您应该返回异步响应。
return admin.messaging().send(message)
.then((response) => {
console.log(`Step 4 ${userId}`)
// Response is a message ID string.
return console.log('Successfully sent message:', response);
// detailed information about result if send succeded but something went wrong
// console.log(response.results[0].error);
})
.catch((error) => {
return console.log('Error sending message:', error);
});
}
console.log(`Step 5 ${userId}`)