Firebase 云功能 Firestore 触发器 onWrite 在本地测试时未按预期运行
Firebase cloud function Firestore trigger onWrite not behaving as expected when testing locally
我正在使用 Firebase 函数在 Node 中本地测试 Firestore 触发的 Firebase 云函数 Shell。
当使用 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
})
在调用之前和之后模拟文档更新时 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 触发器,您需要在所有情况下声明文档的 "before" 和 "after" 状态。您不能尝试通过省略 "before" 或 "after" 键来简化 API。试试这个,例如,如果您只想测试文档创建:
updateMonth({
after:{foo:'new'}
})
此外,如果您的代码只对文档创建感兴趣,那么只在 onCreate 触发器上编写代码可能比尝试在 onWrite 中找出文档状态更容易。就个人而言,我避免使用 onWrite 而使用其他三个,因为它们更容易推断出实际发生了什么变化。
经过多次迭代,事实证明解决方案非常简单。
要在使用 firebase 函数 shell 在本地模拟云功能时成功模拟将触发 onWrite 的新文档创建,您需要明确提供 属性 之后,如 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 does not explicity make this clear hence the confusion. Perhaps this may be a nice enhancement to add to firebase-tools firebase functions:shell 上的文档。
我正在使用 Firebase 函数在 Node 中本地测试 Firestore 触发的 Firebase 云函数 Shell。
当使用 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
})
在调用之前和之后模拟文档更新时 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 触发器,您需要在所有情况下声明文档的 "before" 和 "after" 状态。您不能尝试通过省略 "before" 或 "after" 键来简化 API。试试这个,例如,如果您只想测试文档创建:
updateMonth({
after:{foo:'new'}
})
此外,如果您的代码只对文档创建感兴趣,那么只在 onCreate 触发器上编写代码可能比尝试在 onWrite 中找出文档状态更容易。就个人而言,我避免使用 onWrite 而使用其他三个,因为它们更容易推断出实际发生了什么变化。
经过多次迭代,事实证明解决方案非常简单。
要在使用 firebase 函数 shell 在本地模拟云功能时成功模拟将触发 onWrite 的新文档创建,您需要明确提供 属性 之后,如 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 does not explicity make this clear hence the confusion. Perhaps this may be a nice enhancement to add to firebase-tools firebase functions:shell 上的文档。