【问题标题】:Firebase firestore: how to query relevant documents and then update each of themFirebase firestore:如何查询相关文档然后更新每个文档
【发布时间】:2020-07-27 03:46:22
【问题描述】:

我正在 Firebase/firestore 上开发一个网络应用,用户可以在其中登录并撰写自己的帖子。数据存储方式如下:

-用户信息存储在collection('user').doc('uid')下。

-关于用户撰写的帖子的信息存储在collection('post').doc('postid') 中,并且该文档具有'userinfo' 和'uid' 字段。 'userinfo' 字段包含存储在 'uid' doc 中的内容的精确副本,只是对象格式。

以下是我想做的操作:

  1. 当用户更改数据时,更改会反映在文档中。

  2. 根据“uid”数据查找用户写过的所有帖子,然后更新这些数据中的用户信息。

最后一部分对我来说很棘手。 Firebase 文档涵盖了引用几乎是静态的情况,即您知道写入/更新的确切路径。我要做的是寻找一组不一定是静态的文档,然后更新它们。

这是我为此工作编写的代码。第一部分工作没有任何问题。当然,第二部分不起作用。 :) 做第二部分的代码是什么?

 const update = () => {
             //This part is for updating user information. This works without any problem.
             firebase.firestore().collection('user').doc(user.uid).update({
                 username: username1,
                 nickname: nickname1,
                 intro: intro1 
             })
            .then(()=>{
             //This part is for updating all of the document that the user has written based on 'uid' value. This doesn't work. 
             //Below code is probably way off, but it shows where I am going and what I am trying to do.
             firebase.firestore().collection('post').where('uid','==',user.uid).get()
                 .then((querysnapshot)=>{
                     querysnapshot.forEach((doc)=>{
                         let ref=firebase.firestore().collection('post').doc(doc.id);
                             ref.update({
                                 userinfo: {nickname:nickname1,username:username1,intro:intro1}
                             })
                        })
                     })
                }).then(()=>{
                    alert("Successfully updated!");
                    window.location.href='/'+username1;
                }).catch((error)=>{
                    alert("Error!"); 
                })
}

提前非常感谢!

【问题讨论】:

    标签: javascript firebase google-cloud-firestore


    【解决方案1】:

    运行此代码时遇到什么错误?对我来说,这似乎是在正确的轨道上。

    但尽管如此,以下是一些处理此类更新的建议:

    • 不要在客户端执行第二部分,使用 Firestore 触发器在服务器端执行(在您的情况下,在用户集合中创建 onUpdate 触发器):https://firebase.google.com/docs/functions/firestore-events

      • 在客户端做的问题,是因为如果用户在更新过程中关闭页面/浏览器或者网站下线,就会出现数据不一致的情况。
    • 获取查询结果后不需要重新创建DocumentReference,返回的文档已经有.ref,可以直接调用.ref.update()。

    编辑:如果您想保留原始代码(在客户端更新),在所有更新结束之前发生导航问题是因为 ref.update() 返回了一个承诺。

    因此,当客户端离开时,更新队列是在数据库上异步执行的。

    为了解决这个问题,我会使用 Promise.all() 来等待所有更新完成。

    firebase.firestore().collection('post').where('uid','==',user.uid).get()
       .then((querysnapshot)=>{
           const promises = [];
           querysnapshot.forEach((doc)=>{
               promises.push(doc.ref.update({
                   userinfo: {nickname:nickname1,username:username1,intro:intro1}
               });
           });
           Promise.all(promises).then(()=>{window.location.href='/'+username1;});
       });
    

    或者使用await语法(我觉得更容易维护和理解):

    const querysnapshot = await firebase.firestore().collection('post').where('uid','==',user.uid).get();
    
    const promises = [];
    querysnapshot.forEach((doc)=>{
       promises.push(doc.ref.update({
          userinfo: {nickname:nickname1,username:username1,intro:intro1}
       });
    });
    await Promise.all(promises);
    window.location.href='/'+username1;
    

    【讨论】:

    • 嗨,你是对的。该代码实际上有效。问题是该函数会在操作完成之前加载到新页面。举个例子,按照您的建议将其移动到后端。谢谢!
    • 现在我明白了!我编辑了答案以解决您的原始问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 2020-10-31
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 2021-02-18
    • 2020-09-15
    相关资源
    最近更新 更多