我很难让一个承诺链在firebase Cloud 功能中正确流动 . 它循环遍历ref并返回一组电子邮件以发送通知 . 它有一些嵌套的孩子,我认为这是我出错的地方,但我似乎无法找到错误 .
/courses structure
{
123456id: {
..
members: {
uidKey: {
email: some@email.com
},
uidKey2: {
email: another@email.com
}
}
},
some12345string: {
// no members here, so skip
}
}
function.js
exports.reminderEmail = functions.https.onRequest((req, res) => {
const currentTime = new Date().getTime();
const future = currentTime + 172800000;
const emails = [];
// get the main ref and grab a snapshot
ref.child('courses/').once('value').then(snap => {
snap.forEach(child => {
var el = child.val();
// check for the 'members' child, skip if absent
if(el.hasOwnProperty('members')) {
// open at the ref and get a snapshot
var membersRef = admin.database().ref('courses/' + child.key + '/members/').once('value').then(childSnap => {
console.log(childSnap.val())
childSnap.forEach(member => {
var email = member.val().email;
console.log(email); // logs fine, but because it's async, after the .then() below for some reason
emails.push(email);
})
})
}
})
return emails // the array
})
.then(emails => {
console.log('Sending to: ' + emails.join());
const mailOpts = {
from: 'me@email.com',
bcc: emails.join(),
subject: 'Upcoming Registrations',
text: 'Something about registering here.'
}
return mailTransport.sendMail(mailOpts).then(() => {
res.send('Email sent')
}).catch(error => {
res.send(error)
})
})
})
2 回答
以下应该可以解决问题 .
正如Doug Stevenson在他的回答中所解释的那样,
Promise.all()
方法返回一个单一的promise,当once()
方法返回并推送到promises
数组的所有promise都已解决时,它会解析 .而不是处理来自内部查询内联的所有承诺并将电子邮件推送到数组中,您应该将承诺推送到数组中并使用
Promise.all()
等待它们全部完成 . 然后,迭代快照数组以构建电子邮件数组 .您可能会发现我在 Cloud 函数中使用promises的教程有助于学习一些技巧:https://firebase.google.com/docs/functions/video-series/