Firebase云功能承诺 [英] Firebase cloud function promises

查看:68
本文介绍了Firebase云功能承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难让一个承诺链在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: 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)
    })
  })
})

推荐答案

以下应该可以解决问题.

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: '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)
  });

})

这篇关于Firebase云功能承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆