【发布时间】:2020-04-21 13:07:55
【问题描述】:
这是我尝试使用 firebase 云功能做的事情:
-监听“用户”集合下的文档之一的任何变化。
-更新'comment'和'post'集合中相关文档中用户信息的副本。
因为我需要在相关文档中查询并立即更新它们,所以我正在编写事务操作的代码。
这是我写的代码。它返回错误消息,'函数返回未定义,预期的承诺或值'。
exports.useInfoUpdate = functions.firestore.document('user/{userid}').onUpdate((change,context) => {
const olduserinfo=change.before.data();
const newuserinfo=change.after.data();
db.runTransaction(t=>{
return t.get(db.collection('comment').where('userinfo','==',olduserinfo))
.then((querysnapshot)=>{
querysnapshot.forEach((doc)=>{
doc.ref.update({userinfo:newuserinfo})
})
})
})
.then(()=>{
db.runTransaction(t=>{
return t.get(db.collection('post').where('userinfo','==',olduserinfo))
.then((querysnapshot)=>{
querysnapshot.forEach((doc)=>{
doc.ref.update({userinfo:newuserinfo})
})
})
})
})
});
我有点困惑,因为据我所知,'update' 方法返回一个承诺?我可能会遗漏一些重要的东西,但我是在去年 11 月才开始编程的,所以不要太苛刻。 :)
关于如何解决此问题的任何建议?谢谢!
编辑: 基于Renaud 的出色回答,我创建了以下代码以防有人需要它。 事务的复杂性在于,相同的数据可能存储在不同的索引下或以不同的格式存储。例如相同的“地图”变量可以存储在一个集合的索引下,也可以作为另一个集合的一部分存储。在这种情况下,查询返回的每个文档都需要不同的更新方法。
我使用 doc.ref.path、split 和 switch 方法解决了这个问题。这可以根据集合名称应用不同的更新方法。简而言之,是这样的:
return db.runTransaction(t => {
return t.getAll(...refs)
.then(docs => {
docs.forEach(doc => {
switch (doc.ref.path.split('/')[0]) { //This returns the collection name and switch method assigns a relevant operation to be done.
case 'A':
t = t.update(doc.ref, **do whatever is needed for this collection**)
break;
case 'B':
t = t.update(doc.ref, **do whatever is needed for this collection**)
break;
default:
t = t.update(doc.ref, **do whatever is needed for this collection**)
}
})
})
})
希望这会有所帮助!
【问题讨论】:
标签: javascript node.js firebase google-cloud-functions