我的应用程序的推荐Firebase数据结构
问题是关于我为Firebase应用程序定义的数据结构。 它正在工作,但是,我怀疑它的效率和可扩展性 想象一个聊天应用程序,其中只有一个全局聊天室 但是,您将只看到来自与您有关系的用户的消息。 从这个意义上说,“关系”是指您共享相同的组成员资格。 以下是小组:我的应用程序的推荐Firebase数据结构,firebase,firebase-realtime-database,firebase-security,Firebase,Firebase Realtime Database,Firebase Security,问题是关于我为Firebase应用程序定义的数据结构。 它正在工作,但是,我怀疑它的效率和可扩展性 想象一个聊天应用程序,其中只有一个全局聊天室 但是,您将只看到来自与您有关系的用户的消息。 从这个意义上说,“关系”是指您共享相同的组成员资格。 以下是小组: +---------+---------+---------+ | Group A | Group B | Group C | +---------+---------+---------+ | User1 | User4 | Us
+---------+---------+---------+
| Group A | Group B | Group C |
+---------+---------+---------+
| User1 | User4 | User7 |
| User2 | User5 | User8 |
| User3 | User6 | User1 |
+---------+---------+---------+
请注意,User1是组a和组C的成员。
其概念是,User1将看到用户2、3、7和8发布的消息
而User4只会看到来自User5和User6的消息。
为此,每个用户的关系存储在Firebase实时数据库中,如下所示:
Friends
├── User1
│ ├── User2: true
│ ├── User3: true
│ ├── User7: true
│ └── User8: true
├── User2
├── User1: true
└── User3: true
等等。出于演示目的,我在这里使用用户名,实际上,这些是Firebase UID。
显然,这需要向数据库中写入大量(每个用户组)条目。
每个组的可能组数和用户数是无限的。
这些消息被添加到Firebase中,如下所示:
Messages
├── User1
│ ├── timestamp
│ │ └── message: "This is a message"
│ ├── timestamp
│ │ └── message: "This is another message"
├── User2
├── timestamp
│ └── message: "..."
firebase-url
|
--- users
| |
| ---- userId_1
| | |
| | ---- userName: "John"
| | |
| | ---- userAge: 30
| | |
| | ---- groups
| | |
| | ---- groupName1 : true
| | |
| | ---- groupName2 : true
| |
| ---- userId_2
| |
| ---- userName: "Anna"
| |
| ---- userAge: 25
| |
| ---- groups
| |
| ---- groupName3 : true
| |
| ---- groupName4 : true
|
---- groups
| |
| ---- groupIdId_1
| |
| ---- groupName: "groupName1"
| |
| ---- users
| |
| ---- userId_1: true
| |
| ---- userId_2: true
|
--- messages
|
---- groupId_1
|
---- messageId_1
| |
| ---- messageText: "Hello!"
| |
| ---- messageTimeStamp: 1492189663846
|
---- messageId_2
|
---- messageText: "Hy!"
|
---- messageTimeStamp: 1492189685692
通过以下Firebase安全规则可以轻松实现权限的实际强制执行:
"Messages": {
"$uid": {
// allow read only if the current user is a friend of the message creator
// OR if the user is the creator of the message
".read": "(root.child('Friends/' + $uid + '/' + auth.uid).val() === true || $uid === auth.uid)"
}
}
这是构造数据的推荐方法吗?
我有点不确定,因为跟踪用户关系需要大量的数据。当我们谈论效率和可扩展性时,Firebase中最重要的规则是让数据尽可能平坦。根据此规则,我建议您按照以下方式重新构建数据库:
Messages
├── User1
│ ├── timestamp
│ │ └── message: "This is a message"
│ ├── timestamp
│ │ └── message: "This is another message"
├── User2
├── timestamp
│ └── message: "..."
firebase-url
|
--- users
| |
| ---- userId_1
| | |
| | ---- userName: "John"
| | |
| | ---- userAge: 30
| | |
| | ---- groups
| | |
| | ---- groupName1 : true
| | |
| | ---- groupName2 : true
| |
| ---- userId_2
| |
| ---- userName: "Anna"
| |
| ---- userAge: 25
| |
| ---- groups
| |
| ---- groupName3 : true
| |
| ---- groupName4 : true
|
---- groups
| |
| ---- groupIdId_1
| |
| ---- groupName: "groupName1"
| |
| ---- users
| |
| ---- userId_1: true
| |
| ---- userId_2: true
|
--- messages
|
---- groupId_1
|
---- messageId_1
| |
| ---- messageText: "Hello!"
| |
| ---- messageTimeStamp: 1492189663846
|
---- messageId_2
|
---- messageText: "Hy!"
|
---- messageTimeStamp: 1492189685692
通过这种方式,您可以非常简单地查询数据库,以显示属于单个组的所有用户:firebase url/groups/groupId/users/
。用户所在的所有组:firebase url/users/userId/groups/
以及来自单个组的所有消息:firebase url/groupId\u 1/
要了解有关正确构建Firebase数据库的更多信息,请阅读此内容
希望能有所帮助。很抱歉让您失望,但不幸的是,您无法将此数据结构用于您想要实现的目标 首先,只要组中没有太多用户,数据树的性能就应该良好。我通过重建您概述的数据结构,在Firebase实时数据库中创建玩家之间的“朋友”关系的同时,将一个又一个玩家添加到一个组中,来测试解决方案的性能。结果如下:
Added user #10. Needed time: 0.00156599283218384 seconds
Added user #30. Needed time: 0.00276100635528564 seconds
Added user #50. Needed time: 0.00490301847457886 seconds
Added user #100. Needed time: 0.013949990272522 seconds
Added user #150. Needed time: 0.0460770130157471 seconds
Added user #200. Needed time: 0.0947499871253967 seconds
Added user #300. Needed time: 0.451290011405945 seconds
Added user #400. Needed time: 1.81872600317001 seconds
正如你所看到的,对于小团体来说,表演似乎是完全不错的
但问题主要不在于如何存储数据,而在于如何获取数据。您写道,您希望使用数据库规则获取用户根据其“朋友”关系可以看到的所有消息。但这是某种过滤机制,在Firebase实时数据库中禁止/不可能使用数据库规则进行过滤
从
规则不是过滤器
规则是以原子的方式应用的。这意味着读或写
如果该位置没有规则,操作将立即失败
或者在授予访问权限的父位置。即使每个人都受到影响
子路径可访问,在父位置读取将失败
完全是
还有
.读写规则自上而下,使用较浅的规则
超越更深层次的规则
这意味着您必须直接为消息父节点定义某种读取规则。但该规则将覆盖相应子节点的规则
希望这有帮助 我感谢您的回复,并同意这是典型聊天应用程序的首选结构。然而,在我的示例中,只有一个全局聊天室,没有必要按组跟踪消息。正如您确认的,最重要的方面是保持数据尽可能平坦,我觉得我目前的结构走上了正确的轨道。我真正担心的是可伸缩性方面,例如,当有1000名用户加入一个新用户组时。正如您所说,这是典型聊天应用程序的首选数据库结构。因此,在您的情况下,不要使用
组
部分。在可扩展性方面,使用这种结构不会带来麻烦。我还建议你尝试一个真实的案例场景。以编程方式生成1000个用户。成为第1001个用户,看看会发生什么。所以,祝你好运,随时通知我!;)一切都好吗?我能帮你了解其他信息吗?