如何修复"Function returned undefined, expected Promise or value"



我想在Firebase函数中完成什么:

  1. 从 Firebase 数据库电子邮件地址读取到批量电子邮件。
  2. 循环浏览每个并发送电子邮件。

我相信我在结束承诺方面遇到了问题。这些不需要按顺序运行,我只需要在结束之前解决所有承诺。

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const https = require('axios');
exports.sendEmail = functions.pubsub.topic('nightly_topic').onPublish(() => {
    let emailsToSend = [];
    async function getTests (){
         admin.firestore()
         .collection("tests")
         .get()
         .then(querySnapshot => {
            querySnapshot.forEach(doc => {
                emailsToSend.push(doc.data())
            });
        })
        .catch(function (error) {
            console.error(error);
        });
    }
    async function send (address){
        let body = { 
             //MANDRILL INFO REMOVED
        };
        let endpoint = 'https://mandrillapp.com/api/1.0/messages/send-template.json';
        https.post(endpoint, body)
            .then((result) => {
                console.log('SUCCESS');
            })
            .catch(function (error) {
                console.error(error);
            });
    }
    async function init() {
        await getTests();
        for (const email of emailsToSend) {
            await send(email.address);
        }
    }
    init();
});

函数中缺少返回语句。 return https.post(... etc

试试这个:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const https = require('axios');
exports.sendEmail = functions.pubsub.topic('nightly_topic').onPublish(() => {
    let emailsToSend = [];
    function getTests (){
         return new Promise((resolve, reject) => {
            admin.firestore()
            .collection("tests")
            .get()
            .then(querySnapshot => {
              querySnapshot.forEach(doc => {
                emailsToSend.push(doc.data())
              });
            resolve(emailsToSend);
          })
        .catch(function (error) {
            reject(error)
        });
       });
    }
    async function send (address){
        let body = { 
             //MANDRILL INFO REMOVED
        };
        let endpoint = 'https://mandrillapp.com/api/1.0/messages/send-template.json';
        https.post(endpoint, body)
            .then((result) => {
                console.log('SUCCESS');
            })
            .catch(function (error) {
                console.error(error);
            });
    }
    async function init() {
        const emailsToSend = await getTests();
        for (const email of emailsToSend) {
            await send(email.address);
        }
    }
    init();
});

它可能会对你有所帮助。

所以你快到了。问题是你没有返回任何东西。您应该通过执行以下操作来修复它:

退货承诺

// code ...
exports.sendEmail = functions.pubsub.topic('nightly_topic').onPublish(() => {
    // code
    return init();
}

使用异步

// code ...
exports.sendEmail = functions.pubsub.topic('nightly_topic').onPublish(async () => {
    // code
    await init();
}

注意:异步函数始终返回一个承诺。

建议

在您的代码中,您一次发送电子邮件一封。 await send(email.address); 这行代码等到发送电子邮件后再发送下一封电子邮件,效率不高。

我的建议是同时发送所有电子邮件,并返回一个承诺,该承诺在发送每封电子邮件时都会解决。它应该看起来像这样:

//change this 
for (const email of emailsToSend) {
  await send(email.address);
}
// --------------into this--------------------------------
//This is an array of promises
const promises = emailsToSend.map(email => {
    return send(email.address);
});
await Promise.all(promises);

希望对:)有所帮助

最新更新