T M*_*ack 1 javascript node.js firebase firebase-realtime-database google-cloud-functions
我正在 Firebase Cloud Functions 中构建一个函数,它可以利用 Node.js 模块。
我对 的使用仍然很陌生.then(),并且正在努力找出一种方法来链接我的 3 个函数webhookSend()、emailSendgrid(),并且removeSubmissionProcessor() 这会在'count'递增之后发生(检查 的 if 语句temp_shouldSendWebhook)。返回承诺的整个想法仍然让我有点困惑,特别是当它涉及外部库时。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const request = require('request');
const firebaseConfig = JSON.parse(process.env.FIREBASE_CONFIG);
const SENDGRID_API_KEY = firebaseConfig.sendgrid.key;
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(SENDGRID_API_KEY);
exports.submissionProcess = functions.database.ref('/submissions/processor/{submissionId}').onWrite((change, context) => {
var temp_metaSubmissionCount = 0; // omitted part of function correctly sets the count
var temp_shouldSendWebhook = true; // omitted part of function correctly sets the boolean
return admin.database().ref('/submissions/saved/'+'testuser'+'/'+'meta').child('count')
.set(temp_metaSubmissionCount + 1)
.then(() => {
// here is where im stuck
if (temp_shouldSendWebhook) {
webhookSend();
emailSendgrid();
removeSubmissionProcessor();
} else {
emailSendgrid();
removeSubmissionProcessor();
}
})
.catch(() => {
console.error("Error updating count")
});
});
function emailSendgrid() {
const user = 'test@example.com'
const name = 'Test name'
const msg = {
to: user,
from: 'hello@angularfirebase.com',
subject: 'New Follower',
// text: `Hey ${toName}. You have a new follower!!! `,
// html: `<strong>Hey ${toName}. You have a new follower!!!</strong>`,
// custom templates
templateId: 'your-template-id-1234',
substitutionWrappers: ['{{', '}}'],
substitutions: {
name: name
// and other custom properties here
}
};
return sgMail.send(msg)
}
function webhookSend() {
request.post(
{
url: 'URLHERE',
form: {test: "value"}
},
function (err, httpResponse, body) {
console.log('REQUEST RESPONSE', err, body);
}
);
}
function removeSubmissionProcessor() {
admin.database().ref('/submissions/processor').child('submissionkey').remove();
}
Run Code Online (Sandbox Code Playgroud)
我希望能够构造 3 个函数来依次调用,以便它们全部执行。
为了链接这些函数,它们每个都需要返回一个承诺。当它们这样做时,您可以像这样按顺序调用它们:
return webhookSend()
.then(() => {
return emailSendgrid();
})
.then(() => {
return removeSubmissionProcessor();
});
Run Code Online (Sandbox Code Playgroud)
或者像这样并行:
return Promise.all([webhookSend, emailSendgrid, removeSubmissionProcessor]);
Run Code Online (Sandbox Code Playgroud)
现在,要使您的函数返回承诺:
emailSendgrid:看起来这会返回一个承诺(假设sgMail.send(msg)返回一个承诺),所以您不需要更改它。
removeSubmissionProcessor:这调用了一个返回承诺的函数,但不返回该承诺。换句话说,它会触发异步调用 ( admin.database....remove()) 但不等待响应。如果您return在该调用之前添加,这应该可以工作。
webhookSend调用一个接受回调的函数,因此您要么需要使用fetch(基于 Promise 的)而不是request,要么需要将其转换为返回 Promise 以便链接它:
function webhookSend() {
return new Promise((resolve, reject) => {
request.post(
{
url: 'URLHERE',
form: {test: "value"}
},
function (err, httpResponse, body) {
console.log('REQUEST RESPONSE', err, body);
if (err) {
reject(err);
} else {
resolve(body);
}
}
);
});
}
Run Code Online (Sandbox Code Playgroud)