问题描述
我很难让一个承诺链在Firebase云功能中正确流动.它遍历一个ref并返回一系列电子邮件以发送通知.它有一些嵌套的子级,我认为这就是我要出错的地方,但是我似乎找不到错误.
I'm having a hard time getting a promise chain to flow correctly in a firebase cloud function. It loops through a ref and returns an array of emails for sending out notifications. It has some nested children, and I think that's where I'm going wrong, but I can't seem to find the error.
/课程结构
{
123456id: {
..
members: {
uidKey: {
email: [email protected]
},
uidKey2: {
email: [email protected]
}
}
},
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: '[email protected]',
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)
})
})
})
推荐答案
以下应该可以解决问题.
The following should do the trick.
正如道格·史蒂文森(Doug Stevenson)在其回答中所解释的那样,Promise.all()
方法返回一个单独的promise,当由once()
方法返回并被推送到promises
数组的所有promise都已解析时,它会解析.
As explained by Doug Stevenson in his answer, the Promise.all()
method returns a single promise that resolves when all of the promises, returned by the once()
method and pushed to the promises
array, have resolved.
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
return ref.child('courses/').once('value') //Note the return here
.then(snap => {
const promises = [];
snap.forEach(child => {
var el = child.val();
// check for the 'members' child, skip if absent
if(el.hasOwnProperty('members')) {
promises.push(admin.database().ref('courses/' + child.key + '/members/').once('value'));
}
});
return Promise.all(promises);
})
.then(results => {
const emails = [];
results.forEach(dataSnapshot => {
var email = dataSnapshot.val().email;
emails.push(email);
});
console.log('Sending to: ' + emails.join());
const mailOpts = {
from: '[email protected]',
bcc: emails.join(),
subject: 'Upcoming Registrations',
text: 'Something about registering here.'
}
return mailTransport.sendMail(mailOpts);
})
.then(() => {
res.send('Email sent')
})
.catch(error => { //Move the catch at the end of the promise chain
res.status(500).send(error)
});
})
这篇关于Firebase云功能承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!