Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Firebase云功能承诺_Javascript_Firebase_Google Cloud Functions - Fatal编程技术网

Javascript Firebase云功能承诺

Javascript Firebase云功能承诺,javascript,firebase,google-cloud-functions,Javascript,Firebase,Google Cloud Functions,我很难让承诺链在firebase云函数中正确流动。它通过一个ref循环并返回一系列用于发送通知的电子邮件。它有一些嵌套的子对象,我想这就是我出错的地方,但我似乎找不到错误 /课程结构 { 123456id: { .. members: { uidKey: { email: some@email.com }, uidKey2: { email: another@email.com } }

我很难让承诺链在firebase云函数中正确流动。它通过一个ref循环并返回一系列用于发送通知的电子邮件。它有一些嵌套的子对象,我想这就是我出错的地方,但我似乎找不到错误

/课程结构

{
  123456id: {
    ..
    members: {
      uidKey: {
        email: some@email.com
      },
      uidKey2: {
        email: another@email.com
      }
    }
   },
   some12345string: {
     // no members here, so skip
   }
}
function.js

exports.rementeremail=functions.https.onRequest((req,res)=>{
const currentTime=new Date().getTime();
const future=currentTime+17280000;
常量电子邮件=[];
//获取主引用并抓取快照
ref.child('courses/')。一次('value')。然后(snap=>{
snap.forEach(子项=>{
var el=child.val();
//检查“成员”子项,如果不在,则跳过
如果(el.hasOwnProperty(“成员”)){
//在ref处打开并获取快照
var membersRef=admin.database().ref('courses/'+child.key+'/members/')。一次('value')。然后(childSnap=>{
console.log(childSnap.val())
childSnap.forEach(成员=>{
var email=member.val().email;
console.log(email);//日志很好,但由于它是异步的,出于某种原因,在下面的.then()之后
电子邮件。推送(电子邮件);
})
})
}
})
返回电子邮件//数组
})
。然后(电子邮件=>{
log('发送到:'+电子邮件.join());
常量mailOpts={
发件人:'me@email.com',
密件抄送:emails.join(),
主题:“即将注册”,
文本:“关于在这里注册的信息。”
}
返回mailTransport.sendMail(mailOpts)。然后(()=>{
res.send('已发送电子邮件')
}).catch(错误=>{
res.send(错误)
})
})
})

与其内联处理来自内部查询的所有承诺并将电子邮件推送到数组中,不如将承诺推送到数组中,并使用
Promise.all()
等待它们全部完成。然后,迭代快照数组以构建电子邮件数组


您可能会发现我关于在云函数中使用承诺的教程有助于学习一些技术:

与其内联处理来自内部查询的所有承诺并将电子邮件推送到数组中,不如将承诺推送到数组中并使用
Promise.all()
等待它们全部完成。然后,迭代快照数组以构建电子邮件数组


您可能会发现我关于在云函数中使用promises的教程有助于学习一些技术:

下面应该可以做到这一点

正如Doug Stevenson在他的回答中所解释的那样,
Promise.all()
方法返回一个单独的Promise,当
once()
方法返回并推送到
promises
数组的所有Promise都已解析时,该方法将解析

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: '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 => { //Move the catch at the end of the promise chain
      res.status(500).send(error)
  });

})

下面的内容应该可以做到这一点

正如Doug Stevenson在他的回答中所解释的那样,
Promise.all()
方法返回一个单独的Promise,当
once()
方法返回并推送到
promises
数组的所有Promise都已解析时,该方法将解析

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: '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 => { //Move the catch at the end of the promise chain
      res.status(500).send(error)
  });

})

谢谢你的帮助。再往前走一步,当有人要通知时,有没有办法为课程构建一个对象?添加标题、时间等。它们不是承诺,因此无法添加到数组中…有关在何处查找的提示?
admin.database().ref('courses/'+child.key)。once('value')
将返回带有课程对象(包括成员)的承诺。在
promises
数组中,可以很好地混合返回不同类型对象的promises。当
Promise.all()
解析时返回的
results
数组的顺序与初始
promises
数组的顺序相同:然后由您在
then
处理程序中“解析”此数组中所需的信息。希望这有帮助。谢谢你的帮助。再往前走一步,当有人要通知时,有没有办法为课程构建一个对象?添加标题、时间等。它们不是承诺,因此无法添加到数组中…有关在何处查找的提示?
admin.database().ref('courses/'+child.key)。once('value')
将返回带有课程对象(包括成员)的承诺。在
promises
数组中,可以很好地混合返回不同类型对象的promises。当
Promise.all()
解析时返回的
results
数组的顺序与初始
promises
数组的顺序相同:然后由您在
then
处理程序中“解析”此数组中所需的信息。希望这有帮助。