【问题标题】:Firebase cloud function promisesFirebase 云功能承诺
【发布时间】:2023-04-01 03:22:01
【问题描述】:

我很难让 Promise 链在 Firebase 云函数中正确流动。它遍历一个 ref 并返回一组用于发送通知的电子邮件。它有一些嵌套的孩子,我认为这就是我出错的地方,但我似乎找不到错误。

/课程结构

{
  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)
    })
  })
})

【问题讨论】:

    标签: javascript firebase google-cloud-functions


    【解决方案1】:

    以下应该可以解决问题。

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

    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 数组中,承诺返回不同类型的对象。当Promise.all() 已解析时返回的results 数组与初始promises 数组具有相同的顺序:然后由您在then 处理程序中从该数组“解析”您需要的信息。希望这会有所帮助。
    【解决方案2】:

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

    您可能会发现我关于在 Cloud Functions 中使用 Promise 的教程有助于学习一些技术:https://firebase.google.com/docs/functions/video-series/

    【讨论】:

      猜你喜欢
      • 2018-04-19
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 2018-05-24
      • 2017-12-13
      • 2020-03-21
      • 1970-01-01
      • 2019-01-24
      相关资源
      最近更新 更多