gpt4 book ai didi

node.js - 如何减少电子邮件发送时间(使用 nodemailer 和 firebase)?

转载 作者:行者123 更新时间:2023-12-02 02:07:53 25 4
gpt4 key购买 nike

当新 Node 添加到 Firebase 实时数据库中的特定路径时,我们编写了向用户及其联系人发送电子邮件的代码。

发送电子邮件的平均时间为 4 分钟。我们认为问题是由于等待一些需要的 promise 。我们希望减少运行时间。你有什么建议吗?提前致谢!

这是我们的代码:

const functions = require("firebase-functions");
const nodemailer = require('nodemailer');
require('dotenv').config()

//for fire store
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();

const { SENDER_EMAIL, SENDER_PASSWORD } = process.env;

exports.sendEmails = functions.database.ref("/devices/{device_ID}/history/{alert_ID}")
.onWrite(
(snapshot, context) => {

sendMail(snapshot, context);

return true;
}
);

async function sendMail(snapshot, context){

const { before, after } = snapshot;

// new alert created
if (before.val() == null) {

console.log('DEBUG:: NEW ALERT');

// get owners uID from device ID
const deviceRef = db.collection('deviceToUid').doc(context.params.device_ID);
const uidDoc = await deviceRef.get();

if(!uidDoc.exists){
functions.logger.info("No such document!");
return;
}

// get users email from uID
const userRef = db.collection('users').doc(uidDoc.data()[context.params.device_ID]).collection('user-info');

// get users contact
const contactRef = db.collection('users').doc(uidDoc.data()[context.params.device_ID]).collection('contacts');

const [userInfo, contactList] = await Promise.all([userRef.get(), contactRef.get()]);

if(userInfo.empty){
functions.logger.info("No such collection!");
return;
}

const email = userInfo.docs[0].id; // owners email

let contacts = []; // initialize contact list

contactList.forEach(
(doc) => {
if(doc.data().confirmed){
contacts.push(doc.id);
}
}
)

const mailTransport = nodemailer.createTransport({
service: 'gmail',
auth: {
user: SENDER_EMAIL,
pass: SENDER_PASSWORD,
},
});

const mailOptions = {
from: 'ALERT <noreply@firebase.com>',
to: email,
bcc: contacts,
subject: `...Motion detected`,
html: `<p dir=ltr>New Alert...</p>`

};

mailTransport.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
}
}

我还建议学习一些关于列表理解的知识,如下所示:

  let contacts = []; // initialize contact list

contactList.forEach(
(doc) => {
if(doc.data().confirmed){
contacts.push(doc.id);
}
}
)

可以简化为更简洁的:

let contacts = contactList.docs
.filter((doc) => doc.data().confirmed)
.map((doc) => doc.id);

最佳答案

您已经非常接近了,但是在顶级函数中缺少一个 await,并且在 sendMail 中缺少一个用于调用 mailTransport.sendMail.

我觉得应该是这样的:

exports.sendEmails = functions.database.ref("/devices/{device_ID}/history/{alert_ID}")
.onWrite(
async (snapshot, context) => {
await sendMail(snapshot, context);
return true;
}
);

async function sendMail(snapshot, context){

const { before, after } = snapshot;

// new alert created
if (before.val() == null) {

console.log('DEBUG:: NEW ALERT');

// get owners uID from device ID
const deviceRef = db.collection('deviceToUid').doc(context.params.device_ID);
const uidDoc = await deviceRef.get();

if(!uidDoc.exists){
functions.logger.info("No such document!");
return;
}

// get users email from uID
const userRef = db.collection('users').doc(uidDoc.data()[context.params.device_ID]).collection('user-info');

// get users contact
const contactRef = db.collection('users').doc(uidDoc.data()[context.params.device_ID]).collection('contacts');

const [userInfo, contactList] = await Promise.all([userRef.get(), contactRef.get()]);

if(userInfo.empty){
functions.logger.info("No such collection!");
return;
}

const email = userInfo.docs[0].id; // owners email

let contacts = []; // initialize contact list

contactList.forEach(
(doc) => {
if(doc.data().confirmed){
contacts.push(doc.id);
}
}
)

const mailTransport = nodemailer.createTransport({
service: 'gmail',
auth: {
user: SENDER_EMAIL,
pass: SENDER_PASSWORD,
},
});

const mailOptions = {
from: 'ALERT <noreply@firebase.com>',
to: email,
bcc: contacts,
subject: `...Motion detected`,
html: `<p dir=ltr>New Alert...</p>`

};

await mailTransport.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
return true;
}
}

由于您没有在顶级调用中使用 await,云函数包含将/可能会在异步调用完成之前关闭容器。有关更多信息,请参阅有关 sync, async and promises - and how Cloud Functions are terminated 的文档.

关于node.js - 如何减少电子邮件发送时间(使用 nodemailer 和 firebase)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68146035/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com