node.js - 使用 SMTP 的 Firebase 功能可以在模拟器中运行,但在部署时超时

标签 node.js firebase google-cloud-functions timeout nodemailer

目前我正在 Firebase 中编写一个云函数,以使用 Nodemailer 发送电子邮件,其中包含二维码。

如果我在 Firebase 模拟器中模拟该项目,一切都会正常,并且邮件会正确发送。

但是,当我将代码上传到 Firebase 时,该函数总是在 60 秒后超时。我已经尝试将超时设置得更高,但它仍然发生。

我的代码是:

exports.emailSender = functions.https.onRequest(async (req, res) => {
  var { name, code, hash, dest } = req.body;
  let transporter = nodemailer.createTransport({
    host: "smtp.test.com",
    port: 25,
    auth: {
      user: "username", 
      pass: "password",
    },
  });

  try {
    let qr = await create_qrcode(code+":"+hash,250,50);
    let qrBig = await create_qrcode(code+":"+hash,500,100);

    const mailOptions = {
      from: "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0a646527786f7a66734a7e6f797e246e6f" rel="noreferrer noopener nofollow">[email protected]</a>",
      to: dest,
      subject: "Email Sent via Firebase",
      html: `<img src="${qr}" />`,
      attachments: [
        {
          filename: "QR-Code",
          path: qrBig,
        },
      ],
    };

    await transporter.sendMail(mailOptions, (err, info) => {
      if (err) {
        console.log(err);
        res.send({ error: err.message });
      } else {
        console.log(info);
        res.send("Erfolgreich");
      }
    });
  } catch (error) {
    res.send({ error: error.message });
  }
});

创建二维码的函数是:

async function create_qrcode(dataForQRcode, width, cwidth {
  // grab data you want on qrcode here
  const cvs = createCanvas(1, 1);
  const url = await QRCode.toCanvas(cvs, dataForQRcode, {
    errorCorrectionLevel: "H", // LMQH
    margin: 1,
    color: {
      dark: "#000000", // black pixels
      light: "#ffffff", // white background
    },
  });
  const canvas = createCanvas(width, width);
  const ctx = canvas.getContext("2d");
  const img = await loadImage("./icon.png");
  ctx.drawImage(url, 0, 0, width, width);
  const center = (width - cwidth) / 2;
  ctx.drawImage(img, center, center, cwidth, cwidth);
  return canvas.toDataURL("image/png");
};

该函数似乎在 sendMail() 处卡住,因此没有触发 res.send(),并且在 60 秒后达到超时。

知道为什么这适用于模拟器而不是真正的云功能吗?

最佳答案

作为抵制滥用行为的一种方式,GCP entirely blocks outbound port 25对于 Compute Engine,几乎可以肯定,云函数也会发生同样的事情。

您必须尝试另一种不使用出站端口 25 的方法。例如,您可以使用邮件服务器上的 SMTP 提交端口 587(而不是端口 25)来提交出站电子邮件。这将起作用,因为端口 587(以及用于 smtps 的 465)未被 GCP 阻止。

关于node.js - 使用 SMTP 的 Firebase 功能可以在模拟器中运行,但在部署时超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63256298/

相关文章:

Node.js ENOENT 读取 PDF 文件

ios - 为什么在 iOS 11.4 版本中无法获取设备 token 值和 FCM token 值?

Android Firebase Analytics 事件不显示在控制台上

angular - 如何在我的 Angular 应用程序中使用 Firebase Admin SDK?

node.js - 如何使 Firebase 数据库与 BigQuery 保持同步?

javascript - 在node.js中导出模块

node.js - NPM 5 的依赖项和 devDependency 之间有什么区别

node.js - 如何查看从node.js发送到服务器的请求?

typescript - 使用 typescript 从 web sdk 使用 firebase 函数

firebase - 从 Firebase 函数调用 Google Play Developer API