Основная проблема здесь заключается в невозможности дифференцировать изменения, сделанные этой серверной функцией или клиентом.Всякий раз, когда вы находитесь в этой ситуации, вы должны попытаться провести четкое различие между ними.Вы можете даже подумать о наличии дополнительного поля, например fromServer: true
, которое будет соответствовать обновлениям сервера и поможет серверу игнорировать связанный триггер.Сказав это, я думаю, что определил проблему и дал четкое решение ниже.
Эта строка вводит в заблуждение:
const updated = newDocument && newDocument.updated === oldDocument.updated
Она должна иметь имя:
const updateStatusDidNotChange = newDocument && newDocument.updated === oldDocument.updated
Я понимаю, что вы хотите, чтобы обновленный флаг управлялся этой функцией, а неклиент.Дайте мне знать, если это не так.
Следовательно, поле обновления изменяется только в этой функции.Поскольку вы хотите регистрировать только изменения, сделанные вне этой функции, вы хотите регистрировать только, когда обновление не изменилось.
Вот моя попытка исправить ваш код в этом свете:
export async function landWrite(change, context) {
const newDocument = change.after.exists ? change.after.data() : null
const oldDocument = change.before.data()
const updateStatusDidNotChange = newDocument && newDocument.updated === oldDocument.updated
if (!updateStatusDidNotChange) return true; //this was a change made by me, ignore
const batch = db.batch()
if (!oldDocument.updated) {
const landid = change.after.id
const landRef = db.collection('land').doc(landid)
batch.update(landRef, {'updated': true })
}
const log = {
time: FieldValue.serverTimestamp(),
oldDocument: oldDocument,
newDocument: newDocument
}
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
})
}
Редактировать
У меня была точная проблема, и мне пришлось различать изменения по серверу и клиентуи игнорировать те, которые были с сервера.Я надеюсь, что вы попробуете мое предложение.