Firestore定时触发Cloud Messaging通知内容为空问题求助
问题分析与解决方案:通知内容为空的原因及修复
你的问题核心在于异步操作的执行顺序处理错误。Firestore的get()方法是异步的,你当前的写法里,.then()回调中的quote赋值会在后续的事件循环中执行,但创建dailyQuote和调用admin.messaging().send()的代码是同步运行的——这意味着当你设置body: quote的时候,quote还没有被赋值(依然是初始的undefined),所以通知的内容自然为空。
修复方案(推荐用async/await统一处理异步)
因为你的函数已经声明为async了,直接用await来等待Firestore的查询结果,这样就能保证后续代码在拿到数据之后再执行:
exports.sendDailyQuotes = functions.pubsub.schedule('0 7 * * *').timeZone('Asia/Kolkata').onRun(async (context) => { var today = new Date(); today.setDate(today.getDate() + 1); var currMonth = today.getMonth() + 1; var dateQry = today.getDate() + "-" + currMonth; try { // 用await等待Firestore查询完成,拿到结果 const snapper = await admin.firestore().collection('quotes').doc(dateQry).get(); const quote = snapper.data().english; var dailyQuote = { notification : { title : "Daily Quote", body : quote, }, topic : 'notifications' } let response = await admin.messaging().send(dailyQuote); console.log(response); } catch (reason) { console.log(reason); } });
另一种修复方式(把后续逻辑放到.then()回调内)
如果你坚持要用Promise的.then()写法,需要把创建通知和发送的代码都放到.then()里面,确保它们在quote被赋值之后执行:
exports.sendDailyQuotes = functions.pubsub.schedule('0 7 * * *').timeZone('Asia/Kolkata').onRun(async (context) => { var today = new Date(); today.setDate(today.getDate() + 1); var currMonth = today.getMonth() + 1; var dateQry = today.getDate() + "-" + currMonth; admin.firestore().collection('quotes').doc(dateQry).get().then(snapper => { const quote = snapper.data().english; var dailyQuote = { notification : { title : "Daily Quote", body : quote, }, topic : 'notifications' } return admin.messaging().send(dailyQuote); }).then(response => { console.log(response); }).catch(reason => { console.log(reason); }); });
关键改动说明
- 第一种方案用
await替代.then(),让异步代码看起来像同步代码,逻辑更清晰,也避免了回调嵌套。 - 两种方案都确保了
quote被赋值之后,才会创建通知对象并发送,这样body就会正确获取到Firestore中的字段值。
内容的提问来源于stack exchange,提问作者50_Seconds _Of_Coding
相关产品推荐
相关产品推荐

