【问题标题】:Firestore structure modelFirestore 结构模型
【发布时间】:2018-02-25 22:36:09
【问题描述】:

来自 SQL 背景和观看教程,我正在尝试在 Firestore 中做一个模型来了解事情是如何工作的。我基本上想要模拟用户有多个列表并且每个列表都有他的朋友(以显示朋友的名字)的情况。下面说的有道理吗?

Users
    "john@xyz.com"
         -Name: John Smith

    "celina@xyz.com"
         - Name: Celina West

    "dan@xyz.com"
         - Name: Dan Nelson

Lists
     "john@xyz.com"
           List_Titles
                  "List 1"
                       - <AutoGenId>: Celina West
                       - <AutoGenId>: Dan Nelson

任何带“-”的都是字段,任何带括号的都是文档,任何没有前缀的都是集合。

我在这里发现的一个问题是,假设用户更新了他/她的名字。然后我不仅要去用户集合,还要通过每个子集合列表来查找那个人并更新名称。我考虑过使用电子邮件 ID 而不是名称,但这与“在您查看时构建 nosql db”的方式背道而驰。另外,每次我必须在单独调用每个 Id 以查询名称时点击用户表。

我的假设正确吗? 谢谢

【问题讨论】:

  • 我建议改变这个结构。将键与其包含的数据分离通常是最佳实践。如果电子邮件地址用作键,则对该节点的引用指的是该电子邮件。但是,如果用户更改了他们的电子邮件,这意味着所有引用也需要更改。但是,密钥不能更改,节点需要被读取和重写。添加电子邮件子节点并使用 push() 或 childByAutoId (swift) 创建节点密钥会简单得多,因此它是“通用的”。这样,无需重新创建一堆节点即可更改电子邮件。

标签: android firebase google-cloud-firestore


【解决方案1】:

Snake,没有完美的数据库结构。您需要对数据库进行建模,以便以后在需要执行 CRUD 操作时可以非常轻松地进行查询。在我的tutorials 之一中,我一步一步地解释了我们如何structure 一个包含userslistsproducts 的Firestore 数据库。

请参阅下面的数据库结构,可以帮助实现您想要的。

{
  "users": {
    "appfirstuser@gmail.com": {
      "tokenId": "eGVzwv7Y...",
      "userEmail": "appfirstuser@gmail.com",
      "userName": "First User"
    },
    "appseconduser@gmail,com": {
      "tokenId": "cc8Uhriu...",
      "userEmail": "appseconduser@gmail.com",
      "userName": "Second User"
    }
  },
  "shoppingLists": {
    "appfirstuser@gmail.com": {
      "userShoppingLists": {
       "3Oe37QdcHXSohL2dnNlX": {
        "createdBy": "First User",
        "date": "February 3, 2018 at 2:56:31 PM UTC+2",
        "shoppingListId": "3Oe37QdcHXSohL2dnNlX",
        "shoppingListName": "Pharmacy"
    },
    "  WovuleVbTZdql68gXk84": {
        "createdBy": "First User",
        "date": "February 3, 2018 at 2:56:20 PM UTC+2",
        "shoppingListId": "WovuleVbTZdql68gXk84",
        "shoppingListName": "Grocery"
       }
      }
    }
  },
  "products": {
    "WovuleVbTZdql68gXk84": {
      "shoppingListProducts": {
       "8vinaHJyjG4JqFH33YE7": {
        "productId": "8vinaHJyjG4JqFH33YE7",
        "productName": "Milk"
    },
      "JALygtedMHWQcdEoSnPM": {
       "productId": "JALygtedMHWQcdEoSnPM",
       "productName": "Eggs"
    },
      "WFkJMWZSnhJU9iwGeoOi": {
        "productId": "WFkJMWZSnhJU9iwGeoOi",
        "productName": "Bacon"
       }
      }
    }
  }
}

使用类似这样的数据库结构,您将能够非常轻松地创建、读取、更新和删除记录。

【讨论】:

  • 你好,亚历克斯。谢谢你,我会检查你的视频。关于上面的解决方案,让我问你一个问题。假设用户使用电子邮件和密码登录,在下一个屏幕上,您将在顶部显示他的列表名称以及用户名。您将如何更改模型以适应这种情况?或者你会做 2 次查询(一个用于名称,一个用于列表名称)?
  • 我将保持相同的结构,但不是从GoogleSignInAccount 对象获取用户名,而是从FirebaseUser 对象获取它。关于列表,将保持不变。
  • 所以在这种情况下,您将执行 2 次查询。一种是来自 firebase 用户的用户名,另一种是来自列表对象的列表名称,正确吗?基本上,您不建议在列表名称下添加用户名称,以便在一个查询中全部获取(firestore 视频建议按照您查询它的方式构建 dB,您会发现它很混乱)
  • 在上面的数据库结构中,有一个字段名为createdBy,实际上就是userName。因此,您只能查询一次,以获取列表的名称以及用户的名称。是的,这是正确的,按照我们查询的方式构建 dB。没有单一的数据库结构。如果您有其他结构更适合您的用例,这就是我的方式,请随意使用它。干杯!
  • 啊哈,我明白了。对不起,我错过了createby。所以在这种情况下,如果用户更改了名称,那么您必须浏览所有数据库以更改 createdby 字段。我想我很难接受,因为我来自 SQL 背景,但似乎 noSql 就是这样
猜你喜欢
  • 2020-01-22
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 2012-01-07
  • 1970-01-01
  • 2020-04-26
  • 1970-01-01
相关资源
最近更新 更多