通过电子邮件发送在Firebase数据库中注册的所有用户

时间:2018-10-25 14:40:51

标签: javascript node.js typescript firebase google-cloud-functions

我需要向所有在数据库中注册的用户发送电子邮件。问题是,现在我有12000个用户注册。

到目前为止,这是我的代码。它仅适用于少量用户,但现在需要永久运行。即使将内存设置为2 GB,我也会收到此错误Error: memory limit exceeded. Function invocation was interrupted.。这是我现在的代码:

sendEmail.get('/:types/:message', cors(), async (req, res, next) => {
    console.log(5);
    const types = JSON.parse(req.params.types);
    console.log('types', types);
    let recipients = [];
    let mails = [];
    if (types.includes('students')) {
        console.log(1);
        const tmpUsers = arrayFromObject(await admin.database().ref('Users').orderByChild('student').equalTo(true).once('value').then(r => r.val()).catch(e => console.log(e)));
        recipients = recipients.concat(tmpUsers);
    }
    if (types.includes('solvers')) {
        console.log(2);
        let tmpUsers = arrayFromObject(await admin.database().ref('Users').orderByChild('userType').equalTo('person').once('value').then(r => r.val()).catch(e => console.log(e)));
        tmpUsers = tmpUsers.concat(arrayFromObject(await admin.database().ref('Users').orderByChild('userType').equalTo('company').once('value').then(r => r.val()).catch(e => console.log(e))));
        recipients = recipients.concat(tmpUsers);
    }
    if (types.includes('test')) {
        console.log(3);
        mails.push('mail1', 'mail2', 'mail3', 'mail4');
    }
    const calls = [];
    console.log('recipients', recipients);
    if (recipients.length > 0) {
        recipients.forEach(rec => calls.push(admin.auth().getUser(rec.id).then(r => r).catch(e => console.log(5, e))));
    }
    const newMails = await Promise.all(calls).catch(e => console.log(e));
    console.log('newMails', newMails);
    mails = mails.concat(newMails);
    console.log('mails', mails);
    res.end();
});

一些解释。有3种帐户类型。有学生,个人和公司。个人和公司将同时发送电子邮件,而有时我只需要发送电子邮件给学生。这就是为什么我有这个if stack。

现在,我正在尝试从数据库中获取所有电子邮件。如何提高效率?可以运行吗?甚至更好的是,有内置的Firebase方法吗?

1 个答案:

答案 0 :(得分:0)

我将在NodeJS中对异步回调应用分页。仍然需要一些时间才能完成,但可以完成。 Firebase不允许以降序返回,但是您可以执行以下操作:

firebase.database().ref('books').orderByChild('ups').limitToLast(2)

然后设置一个Firebase函数,该函数执行分页并调用它,或者只是设置一个新的Firebase参考对象,然后使用诸如Axios或Fetch API之类的对象进行调用。当然,这可以在NodeJS(服务器端)设置或客户端设置中完成。这是一个很好的关于这个主题的教程:

https://howtofirebase.com/firebase-data-structures-pagination-96c16ffdb5ca