我有一个GCP Firebase函数设置如下:
exports.sendEmail = functions.firestore.document('/work_orders/{documentId}')
.onUpdate(async (change, context) => {
// code here --
// then ends like this:
functions.logger.log('Log Before Interval Start')
const interval = setInterval(async ()=> {
if (attachment && attachment_2){
clearInterval(interval)
functions.logger.log('Attachments Ready')
const resp = await send_email()
functions.logger.log('Doc Created', context.params.documentId, newValue)
functions.logger.log('Resp Created', resp)
return change.after.ref.update({emailSent: true, createEstimateEmail: false})
}, 1000)
functions.logger.log('Log After Interval')
})
一切都很顺利。电子邮件会立即发送。但是,当涉及到change.after.ref.update
部分时,大约需要3分钟才能完成简单的提交。当它最终完成时,它会触发函数再次运行,因为它是onUpdate
。(第二次运行在检查是否应该运行的标志后立即退出(
有没有办法让我马上做出承诺?
更新:日志您可以看到,4分钟后,该功能将被重新触发。此触发必须是由于更新的消防仓库文档。您可以看到它立即结束,因为函数检查createEstimateEmail
,如果是false
则结束。因此,最后一行大约需要4分钟才能运行。(如果我使用谷歌控制台检查Firestore,它在运行结束后的几分钟内也不会更新。(
2022-01-02 10:30:41.968 ASTsendEmail51lrasb9sh8s Function execution started
2022-01-02 10:30:44.058 ASTsendEmail51lrasb9sh8s Log Before Interval Start
2022-01-02 10:30:44.059 ASTsendEmail51lrasb9sh8s Log After Interval
2022-01-02 10:30:44.124 ASTsendEmail51lrasb9sh8s Function execution took 2158 ms, finished with status: 'ok'
2022-01-02 10:30:45.060 ASTsendEmail51lrasb9sh8s Attachments Ready
2022-01-02 10:30:45.060 ASTsendEmail51lrasb9sh8s Attachments Ready
2022-01-02 10:30:51.336 ASTsendEmail51lrasb9sh8s Doc Created vKFOnZ9usRaDiJ6Nu9Yk
2022-01-02 10:30:51.937 ASTsendEmail51lrasb9sh8s Resp Created [ Response { statusCode: 202, body:....
2022-01-02 10:34:20.391 ASTsendEmail51lrfqr7kldb Function execution started
2022-01-02 10:34:20.402 ASTsendEmail51lrfqr7kldb Function execution took 12 ms, finished with status: 'ok'
按照RJC的建议添加了更多的日志记录点/日志后修复了它。从本质上讲,在所有工作完成之前,功能就已经结束了。
这个答案在处理setInterval((时起到了帮助作用:https://stackoverflow.com/a/56469184/7089055
在主onUpdate()
函数中正确工作的最终代码:
async function waitUntil() {
return await new Promise(resolve => {
const interval = setInterval(() => {
if (attachment && attachment_2) {
clearInterval(interval);
const msg = {....};
resolve(msg);
};
}, 1000);
});
}
const msg = await waitUntil()
const resp = await sgMail.send(msg)
return change.after.ref.update({emailSent: true, createEstimateEmail: false})