为我的应用推荐的 Firebase 数据结构
Recommended Firebase data structure for my app
问题是关于我为我的 Firebase 应用程序定义的数据结构。
它正在工作,但是,我对效率和可扩展性表示怀疑。
想象一个只有一个全球聊天室的聊天应用程序
但您只会看到来自与您有关系的用户的消息。
"Relation" 在这个意义上意味着您共享相同的组成员资格。
这些是组:
+---------+---------+---------+
| Group A | Group B | Group C |
+---------+---------+---------+
| User1 | User4 | User7 |
| User2 | User5 | User8 |
| User3 | User6 | User1 |
+---------+---------+---------+
请注意,User1 是 A 组和 C 组的成员。
这个概念是用户 1 将看到用户 2、3、7 和 8 发布的消息
而用户 4 只会看到来自用户 5 和 6 的消息。
为此,每个用户的关系存储在Firebase实时数据库中,如下所示:
Friends
├── User1
│ ├── User2: true
│ ├── User3: true
│ ├── User7: true
│ └── User8: true
├── User2
├── User1: true
└── User3: true
等等。出于演示目的,我在这里使用用户名,实际上,这些是 Firebase UID。
显然,这需要将许多 (users_per_group)² 条目写入数据库。
可能的组数和每个组的用户数是无限的。
消息会像这样添加到 Firebase:
Messages
├── User1
│ ├── timestamp
│ │ └── message: "This is a message"
│ ├── timestamp
│ │ └── message: "This is another message"
├── User2
├── timestamp
│ └── message: "..."
权限的实际执行很容易通过以下 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 中最重要的规则是让数据尽可能扁平化。根据这个规则,我建议你像这样改造你的数据库:
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_1/
要了解有关正确构建 Firebase 数据库的更多信息,请阅读这篇文章 post。
希望对您有所帮助。
很抱歉让您失望了,但不幸的是,您不能使用此数据结构来实现您想要实现的目标。
首先,只要组中的用户不是太多,数据树的性能应该没问题。我通过重建您概述的数据结构并在 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
如您所见,性能对于较小的团体来说似乎完全没问题。
但问题主要不是你想如何存储数据,而是你想如何获取数据。您写道,您希望使用数据库规则来获取允许用户根据其“朋友”关系查看的所有消息。但这是某种过滤机制,借助数据库规则进行过滤 prohibited/not 在 Firebase 实时数据库中是可能的。
Rules Are Not Filters
Rules are applied in an atomic manner. That means that a read or write
operation is failed immediately if there isn't a rule at that location
or at a parent location that grants access. Even if every affected
child path is accessible, reading at the parent location will fail
completely.
还有...
.read and .write rules work from top-down, with shallower rules
overriding deeper rules.
这意味着您必须直接为您的 Messages 父节点定义某种读取规则。但是此规则将覆盖您对各个子节点的规则。
希望对您有所帮助!
问题是关于我为我的 Firebase 应用程序定义的数据结构。 它正在工作,但是,我对效率和可扩展性表示怀疑。
想象一个只有一个全球聊天室的聊天应用程序 但您只会看到来自与您有关系的用户的消息。 "Relation" 在这个意义上意味着您共享相同的组成员资格。 这些是组:
+---------+---------+---------+
| Group A | Group B | Group C |
+---------+---------+---------+
| User1 | User4 | User7 |
| User2 | User5 | User8 |
| User3 | User6 | User1 |
+---------+---------+---------+
请注意,User1 是 A 组和 C 组的成员。 这个概念是用户 1 将看到用户 2、3、7 和 8 发布的消息 而用户 4 只会看到来自用户 5 和 6 的消息。 为此,每个用户的关系存储在Firebase实时数据库中,如下所示:
Friends
├── User1
│ ├── User2: true
│ ├── User3: true
│ ├── User7: true
│ └── User8: true
├── User2
├── User1: true
└── User3: true
等等。出于演示目的,我在这里使用用户名,实际上,这些是 Firebase UID。 显然,这需要将许多 (users_per_group)² 条目写入数据库。 可能的组数和每个组的用户数是无限的。 消息会像这样添加到 Firebase:
Messages
├── User1
│ ├── timestamp
│ │ └── message: "This is a message"
│ ├── timestamp
│ │ └── message: "This is another message"
├── User2
├── timestamp
│ └── message: "..."
权限的实际执行很容易通过以下 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 中最重要的规则是让数据尽可能扁平化。根据这个规则,我建议你像这样改造你的数据库:
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_1/
要了解有关正确构建 Firebase 数据库的更多信息,请阅读这篇文章 post。
希望对您有所帮助。
很抱歉让您失望了,但不幸的是,您不能使用此数据结构来实现您想要实现的目标。
首先,只要组中的用户不是太多,数据树的性能应该没问题。我通过重建您概述的数据结构并在 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
如您所见,性能对于较小的团体来说似乎完全没问题。
但问题主要不是你想如何存储数据,而是你想如何获取数据。您写道,您希望使用数据库规则来获取允许用户根据其“朋友”关系查看的所有消息。但这是某种过滤机制,借助数据库规则进行过滤 prohibited/not 在 Firebase 实时数据库中是可能的。
Rules Are Not Filters
Rules are applied in an atomic manner. That means that a read or write operation is failed immediately if there isn't a rule at that location or at a parent location that grants access. Even if every affected child path is accessible, reading at the parent location will fail completely.
还有...
.read and .write rules work from top-down, with shallower rules overriding deeper rules.
这意味着您必须直接为您的 Messages 父节点定义某种读取规则。但是此规则将覆盖您对各个子节点的规则。
希望对您有所帮助!