Node.js 避免在特殊情况下通过实时数据库触发Firebase功能
有时我们使用实时数据库触发的firebase函数(onCreate/onDelete/onUpdate…)来执行一些逻辑(如计数等) 我的问题是,在某些情况下是否可能避免这种触发。主要是,当我想允许用户将一个巨大的JSON导入firebase时 例如: 在/examples中创建新子级时触发的函数E。通常,用户在/examples中逐个添加示例,并运行函数E来执行一些逻辑。但是,我希望允许用户(从前端)将2000个子项导入到/examples,并且在导入时可以使用函数E完成的逻辑,而无需使用E。因此,在可以执行大量函数的情况下,我不需要触发E。(注:我知道1000个限制) 更新:Node.js 避免在特殊情况下通过实时数据库触发Firebase功能,node.js,firebase,google-cloud-functions,Node.js,Firebase,Google Cloud Functions,有时我们使用实时数据库触发的firebase函数(onCreate/onDelete/onUpdate…)来执行一些逻辑(如计数等) 我的问题是,在某些情况下是否可能避免这种触发。主要是,当我想允许用户将一个巨大的JSON导入firebase时 例如: 在/examples中创建新子级时触发的函数E。通常,用户在/examples中逐个添加示例,并运行函数E来执行一些逻辑。但是,我希望允许用户(从前端)将2000个子项导入到/examples,并且在导入时可以使用函数E完成的逻辑,而无需使用E。
根据已接受的答案,提交了我的答案。据我所知,如果不删除云函数,就无法通过编程禁用它。但是,这引入了一种边缘情况,即在导入时将数据添加到数据库中 一种折衷方法是发出信号,表示您正在上传的数据应该进行后处理。假设您正在上载到
/examples/{pushId}
,而不是将数据库触发器附加到/examples/{pushId}
,而是将其附加到/examples/{pushId}/needsProcessing
(或类似内容)。不幸的是,这样做的代价是不能为onUpdate()
和onWrite()
使用change
对象
const result=wait firebase.database.ref('/examples').push({
标题:“示例1A”,
描述:“这是一个例子”,
附件:{/*…*/},
类别:“-MTjzAKMcJzhhtxwUbFw”,
作者:“johndoe1970”,
需求处理:正确
});
异步函数handleExampleProcessing(快照、上下文){
//如果需要进行后处理,则进行后处理
如果(!snapshot.exists()| |!snapshot.val()){
log('不需要处理,正在退出');
返回;
}
const exampleRef=admin.database().ref(change.ref.parent);///examples/{pushId},作为admin
const data=await exampleRef.once('value');
//对数据做一些事情,比如对其进行变异
//提交更改
返回exampleRef.update({
…数据,
needsProcessing:null/*删除needsProcessing值*/
});
}
const functionsExampleProcessingRef=functions.database.ref(“examples/{pushId}/needsProcessing”);
导出常量handleExampleNeedingProcessingOnCreate=函数SampleProcessingRef.onCreate(handleExampleProcessing);
//仅当您打算编写`needsProcessing=/*一些错误值*/`时才需要此命令,我建议您创建并删除它,然后您可以使用上面的触发器。
export const handleExampleNeedingProcessingUnUpdate=函数SampleProcessingRef.onUpdate((更改,上下文)=>handleExampleProcessing(更改,之后,上下文));
另一种方法是使用功能标志来确定云函数是否执行其主要功能。我的代码中经常包含以下内容:
exports.onUpload = functions.database
.ref("/uploads/{uploadId}")
.onWrite((event) => {
return ifEnabled("transcribe").then(() => {
console.log("transcription is enabled: calling Cloud Speech");
...
})
});
ifEnabled
是一个简单的辅助功能,用于检查(也在实时数据库中)功能是否已启用:
function ifEnabled(feature) {
console.log("Checking if feature '"+feature+"' is enabled");
return new Promise((resolve, reject) => {
admin.database().ref("/config/features")
.child(feature)
.once('value')
.then(snapshot => {
if (snapshot.val()) {
resolve(snapshot.val());
}
else {
reject("No value or 'falsy' value found");
}
});
});
}
我使用它的大部分时间是在会议上的演讲中,以便在适当的时间启用云功能(因为部署所需的时间比演示所需的时间稍长)。但同样的方法也可以在数据导入过程中临时禁用功能。好的,另一种解决方案是 答:在firebase中添加一个新表,如
/triggers queue
,其中添加了所有应触发后台函数的CRUD。在这个表中,我们为每个应该有触发器的表添加一个键——在我们的示例/examples
表中。表示表的任何键也应具有/created
、/updated
和/deleted
键,如下所示
/examples
.../example-id-1
/triggers-queue
.../examples
....../created
........./example-id
....../updated
........./example-id
............old-value
....../deleted
........./example-id
............old-value
请注意,旧值应该从应用程序(前端等)中添加。
我们总是将触发器设置为onCreate打开
/triggers queue/examples/created/{exampleID}
(simulate onCreate)
/triggers queue/examples/updated/{exampleID}
(simulate onUpdate)
/triggers queue/examples/deleted/{exampleID}
(模拟onDelete)
激发函数可以知道处理逻辑所需的所有信息,如下所示:
- 操作类型:从路径(创建、更新或删除)
- 对象的关键点:从路径
- 当前数据:通过读取相应的表(即,
)/examples/id
- 旧数据:来自触发器表
- 您可以将大量数据导入
表,而无需启动任何函数,因为我们不会将其添加到/examples
/triggers队列
- 您可以扇出函数以超过1000/秒的限制。这是通过将触发器设置为on(例如,在创建时扇出)
和/triggers queue/examples/created0/{exampleID}
/triggers queue/examples/created1/{exampleID}
- 更难实施
- 需要从应用程序向firebase写入更多数据(如旧数据)
B-另一种方法(虽然不是答案)是将后台函数中的登录名移动到HTTP函数,并在每次crud操作时调用它。可以使用如下参数:if(status==='dont')return?但这会触发函数,对吗?所以我们跳过逻辑,限制函数。同意-我想我们找到了一个修改版本-我也可以分享一个答案。您提出的问题是,在更新的情况下,我们无法知道旧值。此外,导入功能可能会删除一些键,从而触发更多功能。不过,我会接受答案。请查看我的答案,以获得任何反馈。感谢您及时帮助解决此问题。我害怕