简体   繁体   English

你如何将model的用户和Firebase中的朋友收藏起来?

[英]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. 我会做两个改变。

  1. keep the list is friends separate 保持列表是朋友分开
  2. keep the friends as a set, instead of a single value or array 将朋友保留为一组,而不是单个值或数组

keep the list is friends separate 保持列表是朋友分开

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. 这有很多原因,你至少有两个。

  1. 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. 您将向用户显示所有数据的机会很小,这意味着您只是浪费了一些带宽。

  2. 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. 更好的结构是将用户配置文件列表(当前只是它们的名称)与每个用户的朋友列表分开。

keep the friends as a set 把朋友当作一套

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.

相关问题 您将如何使用 Firebase function 创建反向代理? - How would you create a reverse proxy using a Firebase function? 如何只允许经过身份验证的用户在 Firebase Firestore 中创建集合? - How to allow only authenticated users to create a collection in Firebase Firestore? Firebase 查询所有非好友用户 - flutter - Firebase query all users who are not friends with user - flutter Firebase:如果我在 Firestore 集合中查询一条记录并将一列数据传递到 model,我的应用程序是否会对下一个 model 进行第二次查询? - Firebase: If I query a Firestore collection for a record and pass one column of data into a model, would my app do a second query for the next model? 将 Firebase 认证用户与 Flutter 中的“用户”集合链接 - Linking Firebase Authenticated user with 'users' collection in Flutter Firebase v9 注册新用户并将用户存储在用户集合中 - Firebase v9 signup a new user and store users in a users collection 如何在 Firebase / Firestore 中创建用户时创建嵌套集合,用户可以在其中保存已添加书签的项目 - How to create a nested collection when creating a user in Firebase / Firestore where users can save bookmarked items 如何获取 Firebase 集合中的所有文档(包括不存在的祖先文档)? - How do you fetch all documents (including non-existent ancestor documents) in a Firebase collection? firebase中如何给用户设置规则? - How to set rules to users in firebase? Firebase:如何删除一个集合中的集合? - Firebase: How to delete collection within a collection?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM