Firebase 云函数使用 fetch() 一遍又一遍地循环

Firebase cloud function looping over and over with fetch()

我是第一次使用 Firebase 函数。而且我不确定我做错了什么。如我的网络选项卡中所示,我调用了我的函数 1 次。但是当我对我的云功能执行我的 http 请求时,它会一遍又一遍地循环。

我的功能是处理我网站上的联系表格,并将包含内容的表格发送给我自己。我试图在函数被调用时设置一个变量,但这对我不起作用。

有人可以告诉我我做错了什么吗?

我如何调用我的函数:

 sendEmail(url, {
  name: this.state.name,
  email: this.state.email,
  message: this.state.message,
  key: "env variable here"
}) {
    return fetch(url, {
      body: JSON.stringify(data),
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
      },
      method: "POST",
      mode: "no-cors"
    }).then(response => response.json()); // parses response to JSON
   }

我的 FireBase 云函数:

const functions = require("firebase-functions");
const nodemailer = require("nodemailer");
const secureCompare = require("secure-compare");

const mailTransport = nodemailer.createTransport({
    host: "smtp.gmail.com",
  port: 465,
  secure: true,
  auth: {
    user: "myemail@gmail.com",
    pass: "mypw"
  }
});

exports.sendEmail = functions.https.onRequest((request, response) => {
  const data = JSON.parse(request.body);
  const key = data.key;
  let hasBeenCalled = false;

  // Exit if the keys don't match
  if (!secureCompare(key, functions.config().cron.key)) {
    console.log("The key provided in the request does not match the key set in the environment. Check that", key, "matches the cron.key attribute in `firebase env:get`");
    response
      .status(403)
      .send(
        'Security key does not match. Make sure your "key" URL query parameter matches the ' + "cron.key environment variable.");
    return null;
  }

 const emailRegex = /^(([^<>()\[\]\.,;:\s@"]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
   const email = emailRegex.test(data.email) ? data.email : null;
   const mailOptions = {
     from: data.name + " <test@gmail.com>",
     to: "myemail@gmail.com",
     bcc: email,
     subject: "this is a message",
     text: data.message
   };


  if (!hasBeenCalled) {
    mailTransport
      .sendMail(mailOptions)
      .then(() => {
        this.hasBeenCalled = true;
        console.error("email sent to: " + mailOptions.to);
        console.error("email sent from: " + data.name);
      })
      .catch(error => {
        this.hasBeenCalled = true;
      });
  }
});

通常,如果您的 HTTPS-triggered 函数被多次调用,这意味着您没有发回响应。发送响应是 Cloud Functions 环境知道您已完成的方式,因此它可能会假设出现问题并重试:

exports.sendEmail = functions.https.onRequest((request, response) => {
  const data = JSON.parse(request.body);
  const key = data.key;
  let hasBeenCalled = false;

  // Exit if the keys don't match
  if (!secureCompare(key, functions.config().cron.key)) {
    console.log("The key provided in the request does not match the key set in the environment. Check that", key, "matches the cron.key attribute in `firebase env:get`");
    response
      .status(403)
      .send(
        'Security key does not match. Make sure your "key" URL query parameter matches the ' + "cron.key environment variable.");
    return null;
  }

 const emailRegex = /^(([^<>()\[\]\.,;:\s@"]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
   const email = emailRegex.test(data.email) ? data.email : null;
   const mailOptions = {
     from: data.name + " <test@gmail.com>",
     to: "myemail@gmail.com",
     bcc: email,
     subject: "this is a message",
     text: data.message
   };


  if (!hasBeenCalled) {
    mailTransport
      .sendMail(mailOptions)
      .then(() => {
        this.hasBeenCalled = true;
        console.log("email sent to: " + mailOptions.to);
        console.log("email sent from: " + data.name);
        response.status(200).send("Mail sent");
      })
      .catch(error => {
        console.error(error);
        this.hasBeenCalled = true;
        response.status(500).send(error);
      });
  }
});