我有一个循环函数的情况,找不到解决方案。
有一个集合,其中有一个标志,表明数据是否已更改。还想记录更改。
export async function landWrite(change, context) {
const newDocument = change.after.exists ? change.after.data() : null
const oldDocument = change.before.data()
const log = {
time: FieldValue.serverTimestamp(),
oldDocument: oldDocument,
newDocument: newDocument
}
const landid = change.after.id
const batch = db.batch()
const updated = newDocument && newDocument.updated === oldDocument.updated
if (!updated) {
const landRef = db.collection('land').doc(landid)
batch.update(landRef, {'updated': true })
}
const logRef = db.collection('land').doc(landid).collection('logs').doc()
batch.set(logRef, log)
return batch.commit()
.then(success => {
return true
})
.catch(error => {
return error
})
}
问题是当 UPDATED 标志为 false 时,这会写入日志两次。
但也不能将日志写入 ELSE 语句中,因为该标志已经可以被更新并且进行了新的文档更新,因此必须写入新的日志。
扳机:
import * as landFunctions from './lands/index'
export const landWrite = functions.firestore
.document('land/{land}')
.onWrite((change, context) => {
return landFunctions.landWrite(change, context)
})
最佳答案
如果我理解正确,这里的问题是 updated
标志没有指定更新响应哪个事件(因为你不能真正用 boolean
做到这一点)。换句话说 - 您可能同时有多个“第一阶段”写入 lands
,并且需要一种方法来消除它们的歧义。
以下是我会尝试的一些可能的选择 - 从(恕我直言)最差到最好:
叫了两次。
调用一次,但是您必须维护一个单独的并行
文档/集合旁边
lands
. 选项 1
在
updated
中保存某种唯一标识符字段(例如字符串化 JSON 事件的哈希值 - 例如 hash(JSON.stringify(oldDocument))
或自定义事件 ID [如果您有的话])。选项 2
尝试检查
updateMask
property of the incoming event ,并丢弃任何仅影响该属性的写入事件。选项 3
将您的更新状态存储在不同的文档路径/集合(例如,与您的
landUpdates
集合处于同一级别的 lands
集合),并将您的云函数配置为不在该路径上触发。 (如果需要,您始终可以创建在 landUpdates
路径上触发的第二个云函数,并向其添加相同的逻辑或不同的逻辑。)希望这可以帮助!
关于Firebase 函数 onUpdate 循环问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56356101/