【问题标题】:Firestore update with merge - how to overwrite a part of the documentFirestore 更新与合并 - 如何覆盖文档的一部分
【发布时间】:2019-10-11 08:01:14
【问题描述】:

在 Firestore 中更新文档时,我想保留大部分文档,但更改一个包含对象的属性。

我有什么

{
  name: "John Doe",
  email: "me@example.com",
  friends: {
     a: {...},
     b: {...},
     c: {...},
     d: {...},
     e: {...},
     f: {...},
  }
}

现在,我有一个新的朋友对象,例如 {x: ..., y: ..., z: ...}

我想覆盖文档的 friends 树,但保留所有其他字段。

我想要的样子

{
  name: "John Doe",
  email: "me@example.com",
  friends: {
     x: {...},
     y: {...},
     z: {...},
  }
}

但是,如果我做一个firestore.doc(...).update({friends: {...}}, { merge: true })

我目前得到的

{
  name: "John Doe",
  email: "me@example.com",
  friends: {
     a: {...},
     b: {...},
     c: {...},
     d: {...},
     e: {...},
     f: {...},
     x: {...},
     y: {...},
     z: {...},
  }
}

我知道我可以做两次更新,即删除字段然后重新设置,或者我可以读取文档,更改对象并保存而不合并。

但是是否有一种聪明的方法可以覆盖对象(地图),同时保持文档的其余部分不受影响?

【问题讨论】:

    标签: javascript firebase google-cloud-firestore


    【解决方案1】:

    由于您使用的是update() 方法,您只需要在没有合并选项的情况下调用它。

    firestore.doc(...).update({friends: {...}})
    

    注意update() 有两个不同的签名:

    update(data: UpdateData)
    

    update(field: string | FieldPath, value: any, ...moreFieldsAndValues: any[])
    

    如果你传递给方法的第一个参数是一个对象,它会认为你使用了第一个签名,因此你只能传递一个参数。原来如此

    firestore.doc(...).update({friends: {...}}, { merge: true })
    

    应该会产生以下错误:

    错误:函数 DocumentReference.update() 需要 1 个参数,但调用时使用了 2 个参数。


    另一方面,你可以这样称呼它:

      firestore
        .collection('...')
        .doc('...')
        .update(
          'friends.c',
          'Tom',
          'email', 
          'mynew_email@example.com',
          'lastUpdate',
          firebase.firestore.FieldValue.serverTimestamp()
        );
    

    最后,为了完整,请注意,如果您执行以下操作(传递 one 字符串)

      firestore
        .collection('...')
        .doc('...')
        .update(
          'a_string'
        );
    

    你会得到以下错误

    错误:函数 DocumentReference.update() 需要至少 2 个参数,但调用时使用了 1 个参数。

    这是有道理的:-)

    【讨论】:

    • 谢谢 - 不知何故我没有注意到可以更新对象的特定字段,这很有意义,所以如果我将字段路径作为第一个参数,并且只覆盖它文件的一部分。我还认为我对updateset 方法有点困惑所以我想,当我需要合并时,我会调用set(.... {merge:true{}),当我需要覆盖特定字段时,我会调用update("friends", {...})
    猜你喜欢
    • 1970-01-01
    • 2019-09-01
    • 2020-03-03
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 2021-05-12
    • 2020-10-03
    相关资源
    最近更新 更多