javascript - 如何停止执行 Firebase 触发的 Firebase 函数?
问题描述
背景
据我所知,Firebase 触发的函数可以从一个触发事件中多次运行(我想我可以从 Firebase 的日志中看到这一点)。
由于这可能是一种数据损坏行为,我想实现一些标志,如果它发现标志是true
.
在数据库中创建该对象后,我希望此函数(Typescript)仅运行一次。
例如:
adm.database().ref('/Users/{UserID}')
我计划在数据库中为每个用户节点存储一个键值对:
{"alreadyTriggered":true}
或者将“触发器”存储在单独的节点中,没关系。
然后当 Firebase 决定触发相应的函数时,如果不是第一次运行,我将进行检查并停止该函数的执行:
data = snapshot.val();
if (data.alreadyTriggered) {
return;
}
// The function continues here
执行
(一些括号和括号可能会丢失,它是在浏览器窗口中编写的伪代码-Typescript)
索引.ts:
import * as u from './users';
import * as ff from 'firebase-functions';
import * as adm from 'firebase-admin';
import * as types from './types';
// Triggered function
export const userCreated = ff.database.ref('/Users/{userId}').onCreate((sn, ctx) => {
let user: types.User = sn.val();
console.log(`New user created, User Id: ${ctx.params.userId}`);
return u.onCreated(user);
});
用户.ts:
// Function implementation
export function onCreated(user: types.User): Promise<void> {
return adm.database().ref("/Triggers").once('value', snapshot => {
let data: any = snapshot.val();
const alreadyTriggered: boolean = data.alreadyTriggered;
}).then(alreadyTriggered => {
if (alreadyTriggered) {
// We would like to stop any execution here
return
}
else {
console.log(`Continuing processing`)
}
}).then(() => {
// This code should be reached only if alreadyTriggered is set to false
// do actual work with the user object
//...someNewData
//then save it
adm.database().ref('/Users').child(user.userId).update(someNewData)
})
}
问题
问题是我不知道如何可靠地停止执行该功能。我曾尝试使用return
(不起作用),break
(仅用于循环)并且开始使用throw new Error('Stopping function execution')
,但它似乎并没有可靠地停止 - 有时我在日志中看到该函数确实继续执行,尽管alreadyTriggered
肯定是true
.
问题
如何从其代码中停止执行 Firebase Typescript 函数?
解决方案
您的return
语句没有从顶级函数返回。它只是从您传递给的 lambda 函数返回then()
。您必须将信息沿着 Promise 链传播,以告知下一个回调是否执行其工作。
return adm.database().ref("/Triggers").once('value', snapshot => {
let data: any = snapshot.val();
const alreadyTriggered: boolean = data.alreadyTriggered;
}).then(alreadyTriggered => {
if (alreadyTriggered) {
// We would like to stop any execution here
return false
}
else {
console.log(`Continuing processing`)
return true
}
}).then((continue) => {
// This code should be reached only if alreadyTriggered is set to false
// do actual work with the user object
//...someNewData
//then save it
if (continue) {
return adm.database().ref('/Users').child(user.userId).update(someNewData)
}
})
您还错过了上面返回的承诺的返回update
,这将导致您的函数超时。
请注意,使用 async/await 语法这一切都容易得多。
推荐阅读
- azure - 如何修复“X.509 证书中不存在私钥”
- r - 高度缩放到计数的ggridges
- java - 我坚持做 remove()
- python - 如何将一个列表与一个句子进行匹配,并带上带有id - words 格式的单词列表
- android - 使用 Jetpack 的 Android 导航组件销毁/重新创建的片段
- asp.net-mvc - 多个页面的 MVC 5 属性路由错误
- azure - 使用持久函数中的重试选项,最后一次尝试后会发生什么?
- php - 如何使用 twilio 和 windows scheduler 发送短信?
- generics - 应用前选择函数引用:类型推断问题
- transactions - Sparql 交易