【问题标题】:Firebase Documents with Sub-Collections in Swift using Codable使用 Codable 在 Swift 中带有子集合的 Firebase 文档
【发布时间】:2021-04-17 16:45:46
【问题描述】:

我想创建一个简单的 SwiftUI 应用程序,它使用 FireStore 并有一个集合“recipes”和一个集合“users”用于用户特定的数据。在用户集合中,我想为每个用户添加一个文档,该文档包含用户最喜欢的食谱的子集合。

在客户端,我对用户数据使用这样的东西:

import FirebaseFirestoreSwift
import Foundation

struct Account: Codable {
    @DocumentID var id: String?
    var favoriteRecipes = Set<Recipe>()
}

现在,如果我使用 Codable 支持将文档写入 firebase,它会为一组食谱创建一个 Map(我想这很好,我只是想用另一种方式)。

所以我显然可以“手动”处理子集合,并像使用任何其他独立集合一样使用它。

不过,我想知道在 Swift 中使用 Codable 在 Firebase 中处理子集合是否有某种“最佳实践”?

非常感谢!

【问题讨论】:

  • 这个问题很模糊 - 那段代码想让你以另一种方式怎么样?你还想要什么方法?处理子集合的最佳实践将取决于 handle 的含义。用例是什么 - 或者您想要运行的查询是什么?您能否提供一些未按预期工作的代码示例?

标签: swift firebase google-cloud-firestore swiftui codable


【解决方案1】:

您的问题分为两部分。让我试着逐一回答。

如何处理 Firestore / Codable 中的嵌套数据结构?

Codable 结构上的任何属性都将映射到 Firestore 文档上的相应属性(您可以通过使用 CodingKeys 枚举对此产生一些影响 - 请参阅 this article

嵌套类型将映射到文档上的字典,而数组和其他序列将映射到文档上的数组。

为了检索文档的子集合,您需要执行单独的提取请求。 Firestore 不支持在客户端获取文档/子集合的嵌套树。但是,在服务器上却是另一回事。查看Renaud's article 了解更多信息。

如何存储用户特定的数据?

对于任何 user=specific 数据,我建议使用以下两种方法之一来构建数据:

作为子集合存储

在这种情况下,我们有一个顶级集合 users,其中包含所有用户的文档(让 Firestore 为您自动生成文档 ID,并将 Firebase Auth 的用户 ID 作为属性存储在相应的 @ 987654328@文档。

/(root)
  + users                         <-- (collection)
    + 0FABQ...RiGg                <-- (user document)
      - uid: "6ZPt...BLiK3fnl2"   <-- (Firebase Auth user ID)
      - name: "Johnny Appleseed"  <-- (attribute)
      + recipes (collection)      <-- (sub-collection)
        + A69EF...4EFA            <-- (recipe document)
          - name: "Scones"        <-- (attribute)
    + FCED...12D5                 <-- (another user document)

然后您可以使用用户的 ID(来自 Firebase Auth)来查询所有用户的食谱。

存储为顶级集合

在这种情况下,我们有两个顶级集合:一个用于所有用户,另一个用于所有食谱。为了区分用户的食谱,每个食谱文档都有一个 uid 属性,其中包含相应用户的用户 ID:

/(root)
  + users                         <-- (collection)
    + 0FABQ...RiGg                <-- (user document)
      - uid: "6ZPt...BLiK3fnl2"   <-- (Firebase Auth user ID)
      - name: "Johnny Appleseed"  <-- (attribute)
    + FCED...12D5                 <-- (another user document)
  + recipes (collection)          <-- (collection)
    + A69EF...4EFA                <-- (recipe document)
      - uid: "6ZPt...BLiK3fnl2"   <-- (Firebase Auth user ID)
      - name: "Scones"            <-- (attribute)

要检索用户的食谱,您需要查询所有食谱并过滤与当前登录用户的用户 ID 匹配的食谱。

要了解有关 Firestore 数据建模的更多信息,请查看 the documentation,其中还包含指向许多非常有用的视频的链接。 Fireship 也有一个really good article 关于这个。

【讨论】:

  • 非常感谢。我没有考虑到您不能查询包含文件在内的文档这一事实。所有子集合,因此firebase将对其他“模型”的引用存储为地图而不是任何类型的子集合是完全有道理的。但有一件事:如果我想包含配方的数据(或其中的一部分) ) 在地图中帐户本身的文档中,就像我在顶部的代码示例中发生的那样,如何告诉 firestore 也存储 ID?截至目前,firestore 不包括食谱映射中的食谱的 id(用 @DocumentID 包裹的 id)
猜你喜欢
  • 2018-10-21
  • 2020-08-28
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 2018-01-25
  • 2021-10-30
  • 1970-01-01
相关资源
最近更新 更多