Reputation: 1705
I have a posts
collection in which my application stores all the posts of a user, with the following data structure:
+ uid (the user id of the creator)
+ text-content : String
+ tagged-users: [String]
+ assigned-media: [{"downloadUrl": String, "storageLocation": String}]
+ type: String
+ typestamp: Timestamp
+ Likes
+ uid (the user id of the liking person)
+ timestamp: Timestamp
+ postId (optional, depending on the results of the collection group queries)
Now, I would like to display all the posts of this collection to my user; but only, if the user follows the person who created the post, i.e the uid
field of the post document fits.
I know that it is simple to query the collection if the user only follows one person, i.e. I have one simple where
clause. But: What if my user follows 10.000 people or more? How can I query that?
Also, how should I store the followings
, i.e. the persons a user follows? Using a simple array doesn't seem suitable for me, but with all the other options I can't query the posts collection for posts that come from a person I follow.
I would be grateful for every help I could get!
Upvotes: 5
Views: 2155
Reputation: 3744
This is a kind of complex question (and I'm not 100% sure that this is the right place to ask for it), I will do my best to come with something to get you started,
Disclaimer, this might or not for your use case
Divide your service into 3 collections: - users - followers - posts
users Collection is very straight forward, you just need the document id (you already have it).
{
"andyIsTheBest": {
uid: `andyIsTheBest`
// ...
},
"sophieTheBest": {
uid: `sophieTheBest`,
// ...
},
"andyTheWorst": {
uid: `andyTheWorst`,
// ...
},
}
followers mirror the user's docs id, it should look like this:
{
"andyIsTheBest": {
last_post: 2019,
followers: [
'sophieTheBest', 'andyTheWorst'
],
recent: [
{
post_id: 112233, // from the post collection
seq: 2019
}
]
}
}
Finally, the posts collection looks something like this:
{
"112233": {
seq: 2019,
body: `blabla the cool post`
author: `andyIsTheBest`
}
}
Important, notice the sequence seq
number also the last_post
, you can update this value via cloud functions so you keep track of it, then the rest are just implementations details:
const remove = firebase.firestore.FieldValue.arrayRemove
const union = firebase.firestore.FieldValue.arrayUnion
const follow = async (toFollow, user) => {
await db
.collection('followers')
.doc(toFollow)
.update({ users: union(user) });
}
const unfollow = async (toUnFollow, user) => {
await db
.collection('followers')
.doc(toUnFollow);
.update({ users: remove(user) });
}
const feed = async (user) => {
await db.collection(`followers`)
.where(`followers`, `array-contains`, user)
.orderBy(`last_post`, `desc`)
.limit(10)
.get()
// do whatever business logic you need down here
}
Basically this way, it doesn't matter if you have 1 or 1 Trillion, the queries should be ok.
There are a lot of details I didn't cover but this should be ok to get you started.
Hope this help.
Credits to my coworkers who implemented this at my company ^^
Upvotes: 3