[英]How would you model a collection of users and friends in Firebase?
I'm trying to create a database (json) with Firebase. I searched the docs and the.net but couldn't find a clear way to start.我正在尝试使用 Firebase 创建一个数据库 (json)。我搜索了文档和 the.net,但找不到明确的开始方式。 I want to have a database of users.
我想要一个用户数据库。 each user (represented as UID) should have a nickname and a list of friends.
每个用户(表示为 UID)都应该有一个昵称和一个朋友列表。
I tried making a.json file that looks like this:我尝试制作一个 .json 文件,如下所示:
{
users:{
}
}
and adding it to the Firebase console to get started but it wouldn't work.并将其添加到 Firebase 控制台以开始使用,但它不起作用。 How can I do it?
我该怎么做?
the database should look like this:数据库应如下所示:
{
users:{
UID:{
nickname: hello
friends: UID2
}
UID2:{
nickname: world
friends: UID
}
}
I don't know if I got that right, so I would really appreciate any help you guys could give me at this subject.我不知道我是否做对了,所以我非常感谢你们在这个问题上能给我的任何帮助。 Thanks in advance!
提前致谢!
Seems like a good place to start. 似乎是一个好的起点。 I would make two changes though.
我会做两个改变。
A basic recommendation when using the Firebase Database is to keep your data structure shallow/flat. 使用Firebase数据库时的基本建议是保持数据结构浅/平。 There are many reasons for this, and you have at least two.
这有很多原因,你至少有两个。
With your current data structure, say that you want to show a list of user names. 使用您当前的数据结构,假设您要显示用户名列表。 You can only get that list by listening to
/users
. 您只能通过收听
/users
来获取该列表。 And that means you don't just get the user name for each user, but also their list of friends. 这意味着您不仅要获取每个用户的用户名,还要获取他们的朋友列表。 Chances that you're going to show all that data to the user are minimal, so that means that you've just wasted some of their bandwidth.
您将向用户显示所有数据的机会很小,这意味着您只是浪费了一些带宽。
Say that you want to allow everyone to read the list of user names. 假设您希望允许每个人阅读用户名列表。 But you only want each user to be able to read their own list of friends.
但是您只希望每个用户都能够阅读他们自己的朋友列表。 Your current data structure makes that hard, since permission cascades and rules are not filters .
您当前的数据结构很难,因为权限级联和规则不是过滤器 。
A better structure is to keep the list of user profiles (currently just their name) separate from the list of friends for each user. 更好的结构是将用户配置文件列表(当前只是它们的名称)与每个用户的朋友列表分开。
You current have just a single value for the friends
property. 您当前只有
friends
属性的单个值。 As you start building the app you will need to store multiple friends. 当您开始构建应用程序时,您将需要存储多个朋友。 The most common is to then store an array or list of UIDS:
最常见的是然后存储一个数组或UIDS列表:
[ UID1, UID2, UID3 ]
Or 要么
{
"-K.......1": "UID1"
"-K.......5": "UID2"
"-K.......9": "UID3"
}
These are unfortunately the wrong type for this data structure. 遗憾的是,这些数据结构的类型错误。 Both the array and the second collection are lists: an ordered collection of (potentially) non-unique values.
数组和第二个集合都是列表:(可能)非唯一值的有序集合。 But a collection of friends doesn't have to be ordered, it has to be unique.
但是,不需要订购朋友的集合,它必须是独一无二的。 I'm either in the collection or I'm not in there, I can't be in there multiple times and the order typically doesn't matter.
我要么在收藏中,要么我不在那里,我不能在那里多次,订单通常无关紧要。 That's why you often end up looking for
friends.contains("UID1")
or ref.orderByValue().equalTo("UID1")
operations with the above models. 这就是为什么你经常最终寻找与上述模型相关的
friends.contains("UID1")
或ref.orderByValue().equalTo("UID1")
操作。
A much better model is to store the data as a set. 更好的模型是将数据存储为一组。 A set is a collection of unordered values, which have to be unique.
集合是无序值的集合,必须是唯一的。 Perfect for a collection of friends.
非常适合朋友聚会。 To store that in Firebase, we use the UID as the key of the collection.
要将其存储在Firebase中,我们使用UID作为集合的关键字。 And since we can't store a key without a value, we use
true
as the dummy value. 由于我们无法存储没有值的键,因此我们使用
true
作为虚拟值。
So this leads to this data model: 所以这导致了这个数据模型:
{
users:{
UID:{
nickname: hello
}
UID2:{
nickname: world
}
}
friends:{
UID:{
UID2: true
}
UID2:{
UID: true
}
}
}
There is a lot more to say/learn about NoSQL data modeling in general and Firebase specifically. 对于一般的NoSQL数据建模和Firebase,还有更多的说法/了解。 To learn about that, I recommend reading NoSQL data modeling and watching Firebase for SQL developers .
要了解这一点,我建议阅读NoSQL数据建模并观看Firebase for SQL开发人员 。
I keep a collection of Friends
where the users
field is an array of 2 user ids: ['user1', 'user2']
.我保留了一个
Friends
集合,其中users
字段是 2 个用户 ID 的数组: ['user1', 'user2']
。
Getting the friends of a user is easy:获得用户的朋友很容易:
friendsCollection.where("users", "array-contains", "user1").get()
This should get you all documents where user1 appears.这应该会为您提供 user1 出现的所有文档。
Now the tricky part was on how to query a single friend.现在棘手的部分是如何查询单个朋友。 Ideally, firebase would support multiple values in
array-contains
, but they won't do that: https://github.com/firebase/firebase-js-sdk/issues/1169理想情况下, firebase 将支持
array-contains
中的多个值,但他们不会这样做: https://github.com/firebase/firebase-js-sdk/issues/1169
So they way I get around this is to normalize the users
list before adding the document.所以他们解决这个问题的方法是在添加文档之前规范化
users
列表。 Basically I'm utilizing JS' truthiness to check what userId
is greater, and which is smaller, and then making a list in that order.基本上,我利用 JS 的真实性来检查哪个
userId
更大,哪个更小,然后按该顺序制作一个列表。
when adding a friend:添加好友时:
const user1 = sentBy > sentTo ? sentBy : sentTo
const user2 = sentBy > sentTo ? sentTo : sentBy
const friends = { users: [user1, user2] }
await friendsCollection.add(friends)
This basically ensures that whoever is part of the friendship will always be listed in the same order, so when querying, you can just:这基本上确保了无论谁是友谊的一部分,都将始终以相同的顺序列出,因此在查询时,您可以:
await friendsCollection.where("users", "==", [user1, user2]).get()
This obviously only works because I trust the list will always have 2 items, and trust that the JS truthiness will work deterministically, but it's a great solution for this specific problem.这显然只有效,因为我相信列表总是有 2 个项目,并且相信 JS 真实性会确定性地工作,但它是解决这个特定问题的一个很好的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.