Javascript Firebase云函数对象更新创建递归
我的应用程序有一个简单的云函数来跟踪创建/更新的时间戳。看起来是这样的:Javascript Firebase云函数对象更新创建递归,javascript,node.js,firebase,google-cloud-functions,google-cloud-firestore,Javascript,Node.js,Firebase,Google Cloud Functions,Google Cloud Firestore,我的应用程序有一个简单的云函数来跟踪创建/更新的时间戳。看起来是这样的: export const objectChanges = functions .firestore .document('objects/{id}') .onWrite(event => { const patch: {created_at?: string, updated_at: string} = { updated_at: <string> event.timest
export const objectChanges = functions
.firestore
.document('objects/{id}')
.onWrite(event => {
const patch: {created_at?: string, updated_at: string} = {
updated_at: <string> event.timestamp
};
if (!event.data.previous) {
patch.created_at = event.timestamp;
}
return event.data.ref.set(patch, {merge: true});
});
// We'll only update if the name has changed.
// This is crucial to prevent infinite loops.
if (data.name == previousData.name) return;
一旦我上传了这个函数并在列表中创建/修改了一个对象,它就会开始不断地勾选更新的_。我猜它正在检测它自己对更新的_at字段所做的更改。考虑到文档中显示了此类更新的示例,这种行为让我感到困惑
是否有我遗漏的细微差别,或者这是Firestore bug?如果您检查文档中给出的示例,则会检查一个条件,以查看名称是否更改。如果是,则只执行以下代码。如果它保持不变,它将返回,如下所示:
export const objectChanges = functions
.firestore
.document('objects/{id}')
.onWrite(event => {
const patch: {created_at?: string, updated_at: string} = {
updated_at: <string> event.timestamp
};
if (!event.data.previous) {
patch.created_at = event.timestamp;
}
return event.data.ref.set(patch, {merge: true});
});
// We'll only update if the name has changed.
// This is crucial to prevent infinite loops.
if (data.name == previousData.name) return;
因此,在您的情况下,您还需要检查对象的实际数据(除更新的_at外的所有字段)是否已更改。如果除了updated_at之外,没有任何其他更改,您只需退出该功能。如果您检查文档中给出的示例,则需要检查一个条件,以查看名称是否更改。如果是,则只执行以下代码。如果它保持不变,它将返回,如下所示:
export const objectChanges = functions
.firestore
.document('objects/{id}')
.onWrite(event => {
const patch: {created_at?: string, updated_at: string} = {
updated_at: <string> event.timestamp
};
if (!event.data.previous) {
patch.created_at = event.timestamp;
}
return event.data.ref.set(patch, {merge: true});
});
// We'll only update if the name has changed.
// This is crucial to prevent infinite loops.
if (data.name == previousData.name) return;
因此,在您的情况下,您还需要检查对象的实际数据(除更新的_at外的所有字段)是否已更改。如果除了updated_at之外没有任何其他更改,您只需退出该函数。请特别注意您引用的文档示例代码部分:
// We'll only update if the name has changed.
// This is crucial to prevent infinite loops.
if (data.name == previousData.name) return;
您需要找出一种方法来检测函数执行的更新何时在同一位置触发后续更新。请特别注意您引用的文档示例代码部分:
// We'll only update if the name has changed.
// This is crucial to prevent infinite loops.
if (data.name == previousData.name) return;
您需要找出一种方法来检测函数执行的更新何时在同一位置触发后续更新。当您编写一个由自身触发的函数,但仅更改该更新的\u at字段时,您可以检查以前更新的\u at字段是否在新更新的\u at字段的特定范围内 以下代码位于您的云函数中
.onUpdate( async (change) => {
})
我用了5秒钟,因为
-我不在乎我更新的时间戳是否被关闭了5秒
-我不确定在生产环境中,这种情况在1s中也能工作多久,当您编写一个由自身触发的函数时,模拟器中的云函数大约每隔~0.015秒运行一次,但只更改字段中的更新值,您可以检查以前更新的_at字段是否在新更新的_at字段的特定范围内 以下代码位于您的云函数中
.onUpdate( async (change) => {
})
我用了5秒钟,因为
-我不在乎我更新的时间戳是否被关闭了5秒
-我不确定在生产中,延迟会有多长。这种情况也适用于1s,模拟器中的云函数大约每隔~0.015 s运行一次。在onUpdate触发器中,使用最新的时间admin.firestore.fieldValue.serverTimestamp向文档添加或更新时间戳字段。对于本例,我将调用timestamp变量time onUpdate函数提供了一个前后文档。如果before.time==after.time,则您知道用户进行了更改。如果是之前的时间!==在.time之后,您知道云函数发生了变化
if(snap.before.data().time !== snap.after.data().time){
// The cloud function altered the document.
// Return to prevent recursion!
return;
}
从客户机更新文档时,还要使用最新时间更新时间变量。这样,云函数就不会在执行所需代码之前终止。在onUpdate触发器中,使用最新时间admin.firestore.fieldValue.serverTimestamp向文档添加或更新时间戳字段。对于本例,我将调用timestamp变量time onUpdate函数提供了一个前后文档。如果before.time==after.time,则您知道用户进行了更改。如果是之前的时间!==在.time之后,您知道云函数发生了变化
if(snap.before.data().time !== snap.after.data().time){
// The cloud function altered the document.
// Return to prevent recursion!
return;
}
从客户机更新文档时,还要使用最新时间更新时间变量。这样,云函数就不会在执行所需代码之前终止。看起来您可能遗漏了这一部分:注意:任何时候您写入触发函数的同一文档时,都有创建无限循环的风险。请谨慎使用,并确保在无需更改时安全退出该功能。似乎没有任何示例演示这一点。看起来您可能缺少这一部分:注意:任何时候您写入触发函数的同一文档时,都有创建无限循环的风险。请谨慎使用,并确保在无需更改时安全退出该功能。似乎没有任何一个例子能证明这一点。。。就在你之前几秒钟:DSame pinch:P。。。就在你面前几秒钟:恕我直言,在很多情况下,这种模式会崩溃,我不认为这是一个好的榜样,其他人可以全神贯注地效仿 在很多情况下,这种模式会崩溃,我不认为这是其他人效仿的好例子