Облачная функция Firebase с вложенными обещаниями - PullRequest
0 голосов
/ 12 апреля 2019

Я пытаюсь отправить электронное письмо на основе события 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 Ответ

1 голос
/ 12 апреля 2019

Вам не нужно вкладывать так много обещаний, почему бы вам не попробовать что-то вроде этого:

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

Этот код просто использует все возвращаемые значения из обещаний одно за другим без необходимости делать их доступными для более широкой области.

Или, в качестве альтернативы, если возможно, вы можете превратить все это в асинхронную / ожидающую структуру, и она будет выглядеть намного чище, это будет что-то вроде этого (не проверено):

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);
  });
...