Firestore-如何构建Feed和Follow系统 [英] Firestore - how to structure a feed and follow system

查看:78
本文介绍了Firestore-如何构建Feed和Follow系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Firebase实时数据库用于我的测试社交网络应用程序,在其中您可以关注并接收关注的人的帖子.传统的社交网络. 我的数据库结构是这样的-

I was using Firebase realtime database for my test social network app in which you can just follow and receive post of people you follow. A traditional social network. I structured my database something like this-

Users
--USER_ID_1
----name
----email
--USER_ID_2
----name
----email

Posts
--POST_ID_1
----image
----userid
----date
--POST_ID_2
----image
----userid
----date

Timeline
--User_ID_1
----POST_ID_2
------date
----POST_ID_1
------date

我还有另一个节点"Content",其中仅包含所有用户帖子的ID.因此,如果"A"跟在"B"之后,那么添加到A的时间轴的B的所有职位ID.而且,如果B发布了内容,那么它也会被添加到其所有关注者的时间表中.

I also have another node "Content" which just contained id of the all the user post. So, if "A" followed "B" than all the post id of B where added to A's Timeline. And if B posted something than it was also added to all of its follower's timeline.

现在这是我的实时数据库解决方案,但显然存在一些可伸缩性问题

Now this was my solution for realtime database but it clearly have some scalability issues

  • 如果某人拥有10,000个关注者,则在10,000个关注者的时间轴中添加了新帖子.
  • 如果某人的帖子数量多于每个新关注者在其时间轴中收到的所有帖子,则

这些是一些问题.

现在,我正在考虑将整个事情转移到Firestore上,因为它声称是可伸缩的".因此,我应该如何构建数据库的结构,以便可以在Firestore中消除我在实时数据库中遇到的问题.

Now, I am thinking to shift this whole thing on firestore as its been claimed "Scalable". So how should I structure my database so that problems I faced in realtime database can be eliminated in firestore.

推荐答案

稍后我已经看到了您的问题,但我还将尝试为您提供我能想到的最佳数据库结构.因此,希望您会发现此答案有用.

I've seen your question a little later but I will also try to provide you the best database structure I can think of. So hope you'll find this answer useful.

我正在考虑一种模式,该模式对于usersusers that a user is followingposts有三个顶级集合:

I'm thinking of a schema that has there three top-level collections for users, users that a user is following and posts:

Firestore-root
   |
   --- users (collection)
   |     |
   |     --- uid (documents)
   |          |
   |          --- name: "User Name"
   |          |
   |          --- email: "email@email.com"
   |
   --- following (collection)
   |      |
   |      --- uid (document)
   |           |
   |           --- userFollowing (collection)
   |                 |
   |                 --- uid (documents)
   |                 |
   |                 --- uid (documents)
   |
   --- posts (collection)
         |
         --- uid (documents)
              |
              --- userPosts (collection)
                    |
                    --- postId (documents)
                    |     |
                    |     --- title: "Post Title"
                    |     |
                    |     --- date: September 03, 2018 at 6:16:58 PM UTC+3
                    |
                    --- postId (documents)
                          |
                          --- title: "Post Title"
                          |
                          --- date: September 03, 2018 at 6:16:58 PM UTC+3

如果某人拥有10,000个关注者,但在10,000个关注者的时间轴中添加了新帖子.

if someone have 10,000 followers than a new post was added to all of the 10,000 follower's Timeline.

这根本没有问题,因为这就是在Firestore中修改集合的原因.根据为Cloud Firestore数据库建模的官方文档:

That will be no problem at all because this is the reason the collections are ment in Firestore. According to the official documentation of modeling a Cloud Firestore database:

Cloud Firestore经过优化,可以存储大量小文件.

Cloud Firestore is optimized for storing large collections of small documents.

这就是我将userFollowing添加为集合而不是作为可以容纳其他对象的简单对象/映射的原因.请记住,根据有关限制和配额的官方文档,文档的最大大小为1 MiB (1,048,576 bytes).如果是托收,则托收之下的文件数量没有限制.实际上,Firestore已针对此类结构进行了优化.

This is the reason I have added userFollowing as a collection and not as a simple object/map that can hold other objects. Remember, the maximum size of a document according to the official documentation regarding limits and quota is 1 MiB (1,048,576 bytes). In case of collection, there is no limitation regarding the number of documents beneath a collection. In fact, for this kind of structures is Firestore optimized for.

因此,以这种方式拥有这10,000个关注者,将可以很好地工作.此外,您可以以无需在任何地方复制任何内容的方式查询数据库.

So having those 10,000 followers in this manner, will work perfectly fine. Furthermore, you can query the database in such a manner that will be no need to copy anything anywhere.

如您所见,该数据库非常非规范化,使您可以非常简单地对其进行查询.让我们举个例子,但在创建与数据库的连接并使用以下代码行获取用户的uid之前,请先进行以下操作:

As you can see, the database is pretty much denormalized allowing you to query it very simple. Let's take some example but before let's create a connection to the database and get the uid of the user using the following lines of code:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();

如果要查询数据库以获取某个用户关注的所有用户,则可以在以下引用上使用get()调用:

If you want to query the database to get all the users a user is following, you can use a get() call on the following reference:

CollectionReference userFollowingRef = rootRef.collection("following/" + uid + "/userFollowing");

这样,您可以获取用户关注的所有用户对象.拥有他们的uid,您只需获得他们的所有帖子即可.

So in this way, you can get all user objects a user is following. Having their uid's you can simply get all their posts.

假设您要在时间轴上获取每个用户的最新三篇帖子.当使用非常大的数据集时,解决此问题的关键是将数据加载到较小的块中.我在这篇 帖子 中的回答中做了解释推荐的一种通过将查询游标与limit()方法结合使用来对查询进行分页的方法.我还建议您看一下 视频 更好的理解.因此,要获取每个用户的最新三篇文章,您应该考虑使用此解决方案.因此,首先需要获取要关注的前15个用户对象,然后根据其uid来获取其最新的三篇文章.要获取单个用户的最新三篇帖子,请使用以下查询:

Let's say you want to get on your timeline the latest three posts of every user. The key for solving this problem, when using very large data sets is to load the data in smaller chunks. I have explained in my answer from this post a recommended way in which you can paginate queries by combining query cursors with the limit() method. I also recommend you take a look at this video for a better understanding. So to get the latest three posts of every user, you should consider using this solution. So first you need to get the first 15 user objects that you are following and then based on their uid, to get their latest three posts. To get the latest three posts of a single user, please use the following query:

Query query = rootRef.collection("posts/" + uid + "/userPosts").orderBy("date", Query.Direction.DESCENDING)).limit(3);

在向下滚动时,加载其他15个用户对象并获取其最新的三篇文章,依此类推.除了date之外,您还可以向post对象添加其他属性,例如喜欢,评论,分享等的数量.

As you are scrolling down, load other 15 user objects and get their latest three posts and so on. Beside the date you can also add other properties to your post object, like the number of likes, comments, shares and so on.

如果某人的帖子数量多于每个新关注者在其时间轴中收到的所有帖子,则

If someone have large amount of posts than every new follower received all of those posts in his Timeline.

没办法.无需执行此类操作.我已经在上面解释了原因.

No way. There is no need to do something like this. I have already explained above why.

编辑2019年5月20日:

另一种优化操作的方法是将用户应看到的帖子存储在该用户的文档中.

Another solution to optimize the operation in which the user should see all the recent posts of everyone he follow, is to store the posts that the user should see in a document for that user.

因此,如果我们举一个例子,比如说facebook,您将需要一个包含每个用户的facebook feed的文档.但是,如果单个文档可以容纳的数据太多( 1个Mib ),则需要将这些数据放入集合中,如上所述.

So if we take an example, let's say facebook, you'll need to have a document containing the facebook feed for each user. However, if there is too much data that a single document can hold (1 Mib), you need to put that data in a collection, as explained above.

这篇关于Firestore-如何构建Feed和Follow系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆