firebase Nodejs 异步云函数未完成执行



我正在构建一个Firebase云函数,当我更改数据库中的值时,我会获得数据库中所有用户的UID,然后检查一个名为愿望清单的节点,以查看用户的愿望清单中是否有产品。 如果用户的愿望清单没有产品,云功能会向用户发送通知,并附上消息以填写他的愿望清单。该函数适用于一个用户,但是当我迭代用户的节点并调用我为一个用户所做的工作时,它会在完成所有工作之前完成。我相信问题来自没有正确处理异步函数。任何帮助,不胜感激。谢谢!

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const runtimeOpts = {
timeoutSeconds: 180,
memory: '1GB'
}
admin.initializeApp(functions.config().firebase);
exports.sendAdminNotificationForEmptyWishlists = functions.runWith(runtimeOpts)
.database.ref('/dev/fireNotifCloudFunc')
.onWrite(async () => {   
// get all users uids
const ref = admin.database().ref().child('Influencers')
return ref.once("value")
.then(function(snapshot) {
snapshot.forEach( async function(child) {
await checkUserWishlists(child.key)
})
})
.catch(function(error){
console.log(error); 
});
});
//check users wishlists
async function checkUserWishlists(uid){
var ref = admin.database().ref().child('Articles').child(uid)
ref.once("value")
.then(function(snapshot) {
if(snapshot.exists()){
const wishlistsNumber = snapshot.numChildren();
let wishlistCount = 0
let userHasProduct = false         
var BreakException = {};
try {
snapshot.forEach(function(child) {
wishlistCount = wishlistCount + 1
//wishlist node
if(child.child("articles").exists()){
//user have not empty wishlist
userHasProduct = true
throw BreakException
}
});
}
catch(err){
if (err !== BreakException) throw err;
}
if((wishlistCount === wishlistsNumber) && !userHasProduct){
let fcmToken = (async () => {
fcmToken = await getUserFirestoreFCM(uid).then(()=>{
sendPushNotificationToUser(fcmToken,"emptyWishlists")
return fcmToken
})
.catch((error)=>{
console.log("error getting fcm token " + error);
})
})();
}
}
else{
console.log("user did not exist in articles node" );
return 
}
})
.catch(function(error){
console.log(error); 
});
}
async function getUserFirestoreFCM(uid){
let documentRef = admin.firestore().doc("users_table/" + uid);
documentRef.get().then(documentSnapshot => {
if (documentSnapshot.exists) {
console.log('Document exist')
return  documentSnapshot.get('fcmToken')
}
else {
console.log('Document dosen't exist')
return 
}
})
.catch(function(error){
console.log('error geting fcm token from firestore ' + error);
})
}  
async function sendPushNotificationToUser(fcm,type){
//get fcm token    
if(type === "emptyWishlists"){
//notification content
const payloadEmptyWishlists = {
notification: {
title: `Vos wishlists sont vides !`,
body: "Hello veuillez ajouter des produits dans vos wishlists pour joindre les 
influenceurs dans le fil d'acceil, cheers ! ",
icon: "default",            
sound: "default"
}
};
const options = {        
priority: "high",
timeToLive: 60 * 60 * 24
};
//send notif
return admin.messaging().sendToDevice(fcm, 
payloadEmptyWishlists,options).then(function(response){
console.log('Notification sent successfully:',response);
return
}) 
.catch(function(error){
console.log('Notification sent failed:',error);
});
}
}

这是来自日志的尖叫声

我认为你不应该forEach循环callaback中使用async/await。这通常很棘手。寻找好的解释,我找到了这篇文章。我认为它非常简短和清晰。

在这种情况下,我认为您不需要此async/await,但我必须实现它才能确定。无论如何,如果您仍然需要异步,则上述文章中有解决方法。

最新更新