flutter RealTime数据库或Firestore来创建朋友关系?

44u64gxh  于 2023-06-30  发布在  Flutter
关注(0)|答案(3)|浏览(117)

我试图弄清楚如何构建我的数据,关于用户如何能够彼此创建朋友关系。例如,在我的情况下,我希望有这样的东西:{uid 1:接受,uid 2:接受,uid 3:拒绝,uid 4:待定}。
所以我想有一个朋友的名单,也可以接受拒绝或待定的状态。
我现在只是在看Firestore,但也许我应该用实时数据库来做这件事?无论如何,我会告诉你我的问题时,试图找出一个解决方案与Firestore。
我的第一个想法:

Collection: users
    Document: uid1
         name: ‘something’
         friends: map with array of uid and state

问题:假设用户uid 1非常受欢迎,并且有数百万的朋友,那么朋友字段Map将超过firestore对每个文档1 MB的大小限制。所以我在想怎么解决这个问题…
我的第二个想法:
而不是存储在一个字段中,我想创建子集合朋友,然后每个文档代表一个uid,在每个文档中,我会有一个字段指示状态(接受,拒绝,挂起)。这个解决方案似乎非常有组织的数据明智的,但Firestore收费,每个文件读取和存储一个朋友,每个文件不能有效的成本明智的肯定。

Collection: users
Document: user123
Fields:
- name: "John Doe"
- email: "john.doe@example.com"
- ...
Subcollection: friends
Document: friend456
Fields:
- state: "pending"
- timestamp: 1654390800 (example timestamp)

结论:
每个文档1 MB的大小限制不允许我在一个文档中存储一个朋友列表,每个文档读取的Firestore字符不允许我创建一个朋友的子集合并在每个文档中存储每个朋友,因为这太昂贵了。
有经验的开发人员可以给予我一些指导吗?先谢谢你了

zdwk9cvp

zdwk9cvp1#

谢谢你的回复。
为了提供更清晰的说明,假设用户有一个名为“我的朋友”的按钮,当他们点击时,弹出一个可滚动的列表,其中包含带有名称的列表块和来自Firebase存储的图像URL。如果用户向下滚动,那么在每个渲染的列表块中向Firestore收取1次读取的费用似乎有点太昂贵了?我知道我可以在当地储存,但我想知道更多有经验的人如何解决这类问题。正在创建:

Collection: users
    Document: user123
        Fields:
        - name: "John Doe"
        - email: "john.doe@example.com"
        - ...
        Subcollection: friends
            Document: friend456
                Fields:
                - state: "pending"
                - timestamp: 1654390800 (example timestamp)
                - name
                - something else

你认为这是可扩展的吗?或者你认为我应该使用实时数据库,AWS或Hasura?

ssgvzors

ssgvzors2#

第一种方法和你描述的完全一样。
考虑到第二种方法,即有一个朋友子集合,那么你必须认为让一个用户成为朋友很容易,但是如果你需要,例如,查询所有有一些条件超过朋友的用户,这种情况下你将无法轻松实现。这是因为你需要一个接一个地查询所有的用户,并获取他们的朋友的信息(这是相当昂贵的,因为你需要读取更多的数据)。
如果当前的问题是检索某个特定用户的所有挂起用户,我将使用第二种方法。请记住,如果每个用户有500个朋友,那么您的应用程序将能够承受这种类型的查询。此外,你不完全可能想把所有的500个一百个用户在一个单一的镜头,而是你可以使用分页,让你得到只有一定数量的文件。这在你有很多朋友的情况下真的很有帮助。
最后,您可能需要考虑在为每个文档集合设置字段之前需要在UI中显示哪些属性。例如,如果你需要显示一个用户有多少个待处理的好友请求,你可能想在用户文档中包含一个pending_request字段来显示这一小部分数据。这样就避免了检索所有用户并在UI端执行计数(这是昂贵的)。
编辑:是的,但请记住,如果有500个用户,大多数用户不会将列表滚动到底部。分页是要走的路。只显示5个用户,一旦到达列表底部,就再加载5个用户。在firebase文档中有一些关于分页的文档。
Firebase docs regarding pagination

9wbgstp7

9wbgstp73#

IMHO,我会用第一种方法,但有一点变化。既然您说所有UID及其状态可能不适合放在一个文档中,而且您是对的,那么为什么不将它们存储在多个文档中呢?在我看来,您可以从单个文档开始,当文档变大时,创建另一个文档,依此类推。您的数据库模式可能如下所示:

db
|
--- users (collection)
     |
     --- $uid (document)
          |
          --- name: "John Doe"
          |
          --- email: "john.doe@example.com"
          |
          --- friends (sub-collection)
               |
               --- 1 (document)
                   |
                   --- requests (map)
                        |
                        --- uid: "status"
                        |
                        --- uid: "status"

如果你还需要一个时间戳,那么你可以在requestsMap中创建对象,而不是键值对。
使用这种解决方案,您将不得不为阅读用户详细信息的文档读取和读取请求的另一个读取付费。如果一个用户非常受欢迎,比如说100万个请求,那么你可能需要支付3-4次(未测试)额外的读取。
将好友作为单独的文档添加到集合中,这根本不是一个解决方案。我这么说是因为你必须为每个好友请求支付一次阅读费用,而在热门用户的情况下,你必须支付数百万次阅读费用。除此之外,如果一个朋友改变了名字,例如,你必须为用户发送的每个请求支付写操作。所以它可能非常非常昂贵。

相关问题