【问题标题】:Updating firestore using previous state使用以前的状态更新 Firestore
【发布时间】:2018-01-06 15:53:28
【问题描述】:

是否可以使用以前的状态更新 Firestore?

例如,我有一个地址文档,其中有一个users 字段,其中包含与该地址关联的用户数组。 每当我想向这个数组添加新用户时,我都需要前一个数组,否则我最终会用新数据覆盖当前数据。

所以我最终得到了类似的东西。

   firestore()
    .collection("addresses")
    .doc(addressId)
    .get()
    .then(doc => {
      this.db
        .collection("addresses")
        .doc(addressId)
        .update({
          users: [...doc.data().users, id]
        })
    });

有没有办法不用嵌套调用就可以访问之前的数据?

如果没有

有没有更好的方法来管理关系?

【问题讨论】:

    标签: javascript firebase google-cloud-firestore


    【解决方案1】:

    如果您需要以前的值来确定新值,则应使用transaction。这是确保不同客户端不会意外覆盖彼此操作的唯一方法。

    不幸的是,事务也需要嵌套调用,因为这是获取当前值的唯一方法,甚至还有一个额外的包装器(用于事务。

    var docRef = firestore()
        .collection("addresses")
        .doc(addressId);
    
    return db.runTransaction(function(transaction) {
        // This code may get re-run multiple times if there are conflicts.
        return transaction.get(docRef).then(function(doc) {
            transaction.update(docRef, { users: [...doc.data().users, id ]});
        });
    }).then(function() {
        console.log("Transaction successfully committed!");
    }).catch(function(error) {
        console.log("Transaction failed: ", error);
    });
    

    最佳解决方案是使用不需要当前值来添加新值的数据结构。这是Firebase recommends against using arrays 的原因之一:当多个用户可能向数组添加项目时,它们本质上很难扩展。如果不需要维护用户之间的顺序,我建议为用户使用类似集合的结构:

    users: {
      id1: true,
      id2: true
    }
    

    这是一个包含两个用户(id1id2)的集合。 true 值只是标记,因为您不能拥有没有值的字段。

    使用这种结构,添加用户很简单:

    firestore()
        .collection("addresses")
        .doc(addressId)
        .update({ "users.id3": true })
    

    另见Firestore documentation on Working with Arrays, Lists, and Sets

    【讨论】:

    • 事务 api 正是我想要的,谢谢!我打算采用第二种方案,去掉阵列,我觉得管理起来会容易很多。谢谢弗兰克。
    猜你喜欢
    • 2021-03-14
    • 2020-09-12
    • 2021-09-05
    • 1970-01-01
    • 2023-01-28
    • 2020-11-30
    • 1970-01-01
    • 2020-11-27
    • 2021-03-01
    相关资源
    最近更新 更多