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);
});
}
});
我是第一次使用 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);
});
}
});