Javascript 承诺解决后如何调用函数?
下面的代码是针对我的FCM函数的,在构建要发送的有效负载之前,我正在侦听firestore获取令牌。每次发送时,系统都会记录令牌为空。发送fcm时,如何确保其不为空Javascript 承诺解决后如何调用函数?,javascript,firebase,google-cloud-functions,firebase-cloud-messaging,Javascript,Firebase,Google Cloud Functions,Firebase Cloud Messaging,下面的代码是针对我的FCM函数的,在构建要发送的有效负载之前,我正在侦听firestore获取令牌。每次发送时,系统都会记录令牌为空。发送fcm时,如何确保其不为空 let functions = require('firebase-functions'); let admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); exports.sendNotification =fu
let functions = require('firebase-functions');
let admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification =functions.firestore.document('chatrooms/{chatRoomId}/messages/{messageId}')
.onWrite((snap, context) => {
let message = snap.after.data().messageBody;
let messageSender = snap.after.data().senderName;
let messageUserId = snap.after.data().userId;
let chatRoomId = context.params.chatRoomId;
let tokens = [];
let chatRoomRef = admin.firestore().collection("chatrooms").doc(chatRoomId);
return admin.firestore().runTransaction(t => {
return t.get(chatRoomRef)
.then(chatroom => {
let usersArray = chatroom.data().chatMembers;
usersArray.forEach(user_id => {
let userIdRef = admin.firestore().collection("tokens").doc(user_id);
return t.get(userIdRef).then(doc => {
if (doc.exists) {
let user_token = doc.data().token;
functions.logger.log('token: ', token);
tokens.push(user_token);
}
}).catch(err => {
functions.logger.error(err);
})
});
});
}).then(() => {
//The transaction has run successfully, we expect tokens array to not be empty
functions.logger.log("Construction the notification message.");
const payload = {
data: {
data_type: "data_type_chat_message",
title: "Tuchat",
message: message,
sender_id: messageUserId,
sender_name: messageSender,
chatRoom_id: chatRoomId
}
};
const options = {
priority: "high",
timeToLive: 60 * 60 * 24
};
return admin.messaging().sendToDevice(tokens, payload).catch(err => {
functions.logger.error(err);
});
}).catch(err => {
functions.logger.error('Transaction error: ', err);
})
});
在尝试交易之前,它还返回空令牌。问题在于您在forEach循环中处理承诺的方式。循环不会等待承诺被解析为它内部的代码。它目前只是在每个用户ID上以尽可能快的速度迭代,而不是等待查询在其中完成。这意味着代码将在
令牌
填充之前继续
相反,您应该收集循环中的每个承诺,并使用Promise.all()
等待整个批处理,然后从中返回承诺以指示所有工作何时完成。这将确保tokens
在执行链中的下一个之前包含您想要的所有内容
代码的一般形式如下所示:
.then(() => {
const promises = []
collection.forEach(item => {
const promise = doSomeWork()
promises.push(promise)
})
return Promise.all(promises)
})
.then(() => {
// this will continue only after all promises are resolved
})
另见: