带有嵌套承诺的Firebase云功能

时间:2019-04-11 21:58:41

标签: javascript firebase promise google-cloud-firestore

我正在尝试基于集合onAdd事件发送电子邮件 我需要发送电子邮件的信息来自3个不同的集合 所以我当时想设置我需要的所有数据,然后继续发送电子邮件,但是,当我来到实际的电子邮件中时,发送的所有信息都不确定,因此显然变量设置不正确

这是我的代码

exports.sendRepairInitiatedEmail = functions.firestore.document('repairs/{id}').onCreate((snap, context) => {
  const repair = snap.data(); <--- this is set correctly
  let customer;
  let configuration;
  return admin
    .firestore()
    .collection('customers')
    .doc(repair.customerId)
    .get()
    .then(dbCustomer => {
      customer = dbCustomer; <--- customer seems undefined
      return admin
        .firestore()
        .collection('configuration')
        .where('clientId', '==', repair.clientId)
        .get()
        .then(conf => {
          configuration = conf; <-- configuration seems undefined
          console.log('Sending email to  ' + customer.customerEmail);
          const msg = {
            to: customer.customerEmail,
            from: configuration.companyEmail,
            templateId: 'sendGridid',
            dynamic_template_data: {
              name: customer.customerName,
              device: repair.device,
              accessCode: repair.accessCode,
              storeName: configuration.storeName,
              phone: configuration.phoneNumber,
            },
          };
          return sgMail.send(msg);
        });
    })
    .then(() => console.log('Repair initiated email successfully sent to ' + customer.customerName));
});

代码看起来也很复杂,我想避免太多的承诺嵌套 任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

您不必嵌套太多的承诺,为什么不尝试这样的事情:

exports.sendRepairInitiatedEmail = functions.firestore.document('repairs/{id}').onCreate((snap, context) => {
  const repair = snap.data(); 
  let getCustomer = admin
    .firestore()
    .collection('customers')
    .doc(repair.customerId)
    .get();
  let getConfig = admin
    .firestore()
    .collection('configuration')
    .where('clientId', '==', repair.clientId)
    .get();
  return Promise.all([getCustomer, getConfig])
    .then(values => {
        const [customer, configuration] = values;
        console.log('Sending email to  ' + customer.customerEmail);
          const msg = {
            to: customer.customerEmail,
            from: configuration.companyEmail,
            templateId: 'sendGridid',
            dynamic_template_data: {
              name: customer.customerName,
              device: repair.device,
              accessCode: repair.accessCode,
              storeName: configuration.storeName,
              phone: configuration.phoneNumber,
            },
          };
          console.log('Repair initiated email successfully sent to ' + customer.customerName);
          return sgMail.send(msg);
    }); 
});

此代码仅使用从promise传来的所有返回值,而无需将它们用于更大的范围。

或者,如果可能的话,您可以将整个内容转换为async / await结构,看起来会更加整洁,就像这样(未经测试):

exports.sendRepairInitiatedEmail = functions.firestore.document('repairs/{id}').onCreate(async (snap, context) => {
    const repair = snap.data(); 
    const customer = await admin
      .firestore()
      .collection('customers')
      .doc(repair.customerId)
      .get();
    const configuration = await admin
      .firestore()
      .collection('configuration')
      .where('clientId', '==', repair.clientId)
      .get();
    console.log('Sending email to  ' + customer.customerEmail);
    const msg = {
        to: customer.customerEmail,
        from: configuration.companyEmail,
        templateId: 'sendGridid',
        dynamic_template_data: {
        name: customer.customerName,
        device: repair.device,
        accessCode: repair.accessCode,
        storeName: configuration.storeName,
        phone: configuration.phoneNumber,
        },
    };
    console.log('Repair initiated email successfully sent to ' + customer.customerName);
    return await sgMail.send(msg);
  });
相关问题