【问题标题】:update only one document id in subcollection in firestore in reactjsreactjs中firestore的子集合中只更新一个文档ID
【发布时间】:2020-12-29 03:04:56
【问题描述】:

是否可以只更新 firestore 子集合中的一个文档 ID,我一直在寻找解决方案,但我能找到的只是查询所有文档。如果我使用 querySnapshot.foreach() 子集合中具有相同字段值的所有文档都会更新。使用 .where() 还可以查询所有文档,而不是特定的 id,但我只是想更新一个。我正在尝试使用文档 ID,但我不知道如何调用子集合的 ID。有没有办法做到这一点?

const currentUser=firebase.auth().currentUser;
const userPost= firebase.firestore().collection('users') 
                .doc(currentUser.uid).collection("post");

const EditPost = async (event) => {
 event.preventDefault();

 await userPost
  .doc() <-- here I've been trying to put the subcollection doc id 
  .set({
    title: title,
    body: body,
    updatedAt: date,
  }, { merge: true })
  .catch((err) => {
    console.log(err)
  })
 }

这里是 firestore 子集合结构 的示例屏幕截图。目前我尝试使用 uuidv4,因此我还可以在添加新文档时创建 postId 的字段值,因为我打算只调用 postId 作为文档 ID,但它也在子集合文档中。

【问题讨论】:

  • 我不清楚你卡在哪里了。如果您知道它的 ID,那么绝对可以更新单个文档。这在documentation 中有介绍。您必须将 ID 传递给doc()
  • 是的,我想不出为子集合调用一个文档 ID 的正确方法
  • 只有一种方法 - 将 ID 传递给 doc()。你现在什么都没通过。
  • 是的,我已经传递了一个 id,我什至使用了 uuidv4 但也不起作用。所以这只是我目前使用的一个例子,我无法找出在子集合中调用 doc() 的 id 的正确方法。我在说的是子集合而不是根集合。我目前正在尝试一些东西,不知道这是否可行。
  • 我仍然不清楚你卡在哪里了。您要么知道现有文档的 ID,要么不知道。如果没有,则必须查询才能找到它。

标签: reactjs firebase google-cloud-firestore


【解决方案1】:

我终于想出了如何为子集合中的单个文档调用文档 ID 并仅编辑特定文档的字段。可能不是最好的解决方案,但我将其分享给那些与我有类似问题的人。

我的 postlist.js 中有一个查询的帖子列表,每个帖子都有一个唯一的键,相当于子集合中的文档 ID。

post 1 - edit
post 2 - edit
post 3 - edit

然后在我的路线上,我使用了使用反应路由器的 useParams id。使用链接我转到 posteditor 页面 PostEditor.js。

<Route path="/posteditor/:id" component={PostEditor} />

通过使用 PostEditor.js 中 useParams 的 id,我现在可以在 EditPost 函数的 .doc() 中分配 id。

const PostEditor = () => {
  const { id } = useParams

  const userPosts = ....;

  const EditPost = async (event) => {
    event.preventDefault();

    await userPosts
     .doc(id) <------*here I used the id from useParams*
     .set({
       title: title,
       body: body,
       updatedAt: date,
     }, { merge: true })
     .catch((err) => {
      console.log(err)
     })
  }

  return ( //// )
}

现在我可以编辑单个文档并在子集合中单独管理每个文档。正如我所说,它可能不是最好的解决方案,但它对我有用且不会出错。

【讨论】:

    【解决方案2】:

    您无需使用 collectoin.set({}) 也可以使用 collection.update({}) 来更新特定的集合字段。

    db.collection("cities").doc("DC").update({
        capital: true
    })
    

    这里我提到了代码。这是参考站点的Link

    【讨论】:

    • 谢谢,但我的问题是关于子集合的,我对根集合没有问题。
    • 你可以这样使用。 db.collection("cities/subcollecion").doc("DC").update({ capital: true }) 在集合中添加路径。
    • 是的,这实际上是关于从单个文档的子集合中调用 doc id 的问题。也许我的问题含糊不清,但我已经更新了上面的帖子以更好地理解我的问题。
    【解决方案3】:

    假设您知道users 集合中文档的ID 和userPosts 集合中文档的ID,您可以按如下方式更新最后一个文档:

    const currentUser = firebase.auth().currentUser;
    const userPosts = firebase.firestore().collection('users') 
                    .doc(currentUser.uid).collection("userPosts");  // <= note the change here, from collection("post") to collection("userPosts")
     
    const userPostId = "8ea3....";
    
    const EditPost = async (event) => {
     event.preventDefault();
    
     await userPosts
      .doc(userPostId) 
      .set({
        title: title,
        body: body,
        updatedAt: date,
      }, { merge: true })
      .catch((err) => {
        console.log(err)
      })
     }
    

    更一般地说,要为您知道路径的文档创建DocumentReference,您需要交替调用collection()doc() 方法。

    您还可以使用斜线分隔的文档路径调用doc() 方法,如下所示。请注意,由于您指向一个文档,因此斜线分隔的路径包含偶数个元素。

    const currentUser = firebase.auth().currentUser;
    const userPostId = "8ea3....";
    
    const userPostRef = firebase.firestore().doc(`users/${currentUser}/userPosts/${userPostId}`)
    

    【讨论】:

    • 一直在这样做,但我坚持只为单个文档调用子集合 doc id,例如 doc(doc.id) 将无法使用它给我一个错误。所以我将 id 更改为 uuid(上图)并保存一个名为 postId 的字段来存储我的 doc id。查询 postId 为我提供了一个列表,其中列出了我可以在我的 doc(postId) 中使用的所有文档 ID,这样它可以工作,但是因为查询了 postId,所有文档字段值都会同时更新,这让我重新开始。与使用 querySnapshot 相同。
    • 我很抱歉,但很难理解你的目标......已经有很多 cmets /responses 写在你的问题周围,但仍然不清楚你想要做什么。我有一种感觉,也许你混淆了字段和文档。我建议您对您的目标做出非常详细的解释,并用一些图表显示您想要做什么、您的输入数据是什么以及期望的结果。
    • 我想要做的是更新子集合中的单个文档,但我坚持如何在 .doc() 中正确写入 id,因为我总是最终更新所有文档 id具有相同的字段名称。如果我在一个集合中有 2 个具有不同 id 的文档,那么它们都会使用相同的值进行更新,这不是我想要做的。但无论如何感谢所有的帮助,我会研究所有这些。
    • 不清楚的是“更新所有具有相同字段名称的文档ID”。如果您定义一个 DocumentReference,那么您只会更新一个文档而不是多个文档。文档路径是唯一的。
    • 如何在不查询所有文档的情况下在子集合中定义它?类似于做 .doc(doc.id) 有可能吗?
    猜你喜欢
    • 2020-08-25
    • 2022-07-08
    • 2018-12-31
    • 2021-08-16
    • 2021-05-12
    • 1970-01-01
    • 2018-10-21
    • 2021-09-02
    • 1970-01-01
    相关资源
    最近更新 更多