【问题标题】:Firebase cloud function Firestore trigger onWrite not behaving as expected when testing locallyFirebase云功能Firestore触发onWrite在本地测试时未按预期运行
【发布时间】:2019-02-11 04:19:05
【问题描述】:

我正在使用 Firebase Functions Shell 在 Node 中本地测试 Firestore 触发的 Firebase Cloud Function。

当使用 onWrite 触发器并通过从函数 shell 调用 updateMonth({foo:'new'}) 传递新文档时,我无法获得对新文档的引用。

exports.updateMonth = functions.firestore
.document('users/{userId}').onWrite((change, context) => {
    const document = change.after.exists ? change.after.data() : null;
    console.log("change.after.exists", change.after.exists)
    console.log("change.before.exists", change.before.exists)
    const oldDocument = change.before.data();
    console.log("Old:",oldDocument)
    return true
})

当同时调用 before 和 after 来模拟文档更新 updateMonth({before:{foo:'old'},after:{foo:'new'}}) 时,它按预期工作。 但是,当仅使用 updateMonth({foo:'new'}) 调用时,前后文档似乎都不存在:

i  functions: Preparing to emulate functions.
Warning: You're using Node.js v8.4.0 but Google Cloud Functions only supports v6.11.5.
+  functions: hi
+  functions: helloWorld
+  functions: updateMonth
firebase > updateMonth({before:{foo:'old'},after:{foo:'new'}})
'Successfully invoked function.'
firebase > info: User function triggered, starting execution
info: change.after.exists true
info: change.before.exists true
info: Old: { foo: 'old' }
info: Execution took 20 ms, user function completed successfully

firebase > updateMonth({foo:'new'})
'Successfully invoked function.'
firebase > info: User function triggered, starting execution
info: change.after.exists false
change.before.exists false
Old: undefined
Execution took 2 ms, user function completed successfully

我不确定如何获得对正在创建的新文档的引用。在这种情况下,我希望 change.after.exists 是正确的。

【问题讨论】:

  • 您的问题有点身份问题。你说它是一个 onWrite 触发器,但你已经展示了一个 onUpdate 触发器。 onUpdate 仅在修改现有文档时触发,beforeafter 文档应始终存在。 onWrite 将触发任何更改(您必须小心检查发生了什么)。你想在这里完成什么?
  • 我的错。感谢您指出 Doug,我已经使用 onWrite 触发器再次测试了代码,并添加了完整的控制台输出以进行澄清。

标签: node.js firebase google-cloud-firestore google-cloud-functions firebase-cli


【解决方案1】:

使用 onWrite 和 onUpdate 触发器,您需要在所有情况下声明文档的“之前”和“之后”状态。您不能尝试通过省略“之前”或“之后”键来简化 API。例如,如果您只想测试文档创建,请尝试以下操作:

updateMonth({
    after:{foo:'new'}
})

另外,如果您的代码只对文档创建感兴趣,那么只在 onCreate 触发器上编写代码可能比尝试在 onWrite 中找出文档状态更容易。就个人而言,我避免使用 onWrite 并使用其他三个,因为它们更容易推断出实际进行了哪些更改。

【讨论】:

  • 谢谢道格!刚刚得出了同样的结论:)
【解决方案2】:

经过多次迭代,结果证明解决方案非常简单。 要成功模拟在使用 firebase 函数 shell 在本地模拟云功能时将触发 onWrite 的新文档创建,您需要显式提供 after 属性,如 updateMonth({after:{foo:'newVal'}})

firebase > updateMonth({after:{foo:'newVal'}})
'Successfully invoked function.'
firebase > info: User function triggered, starting execution
change.after.exists true
change.before.exists false
New: { foo: 'newVal' }
info: Execution took 291 ms, user function completed successfully

https://firebase.google.com/docs/functions/local-emulator#invoke_firestore_functions 的文档没有明确说明这一点,因此造成了混乱。也许这可能是添加到firebase-tools firebase functions:shell 的一个很好的增强功能。

【讨论】:

    猜你喜欢
    • 2022-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2021-09-14
    • 2019-10-06
    相关资源
    最近更新 更多