Well, as others have mentioned, you should generally optimize for reads, but what 'optimize' means is going to depend on your application. If you expect that that it will be pretty infrequent that you have to return posts from several users at the same time, then I would guess it would be a just a bit easier to put the posts under the user, so you can quickly fetch all the posts from a single user. If you're doing something where there are say, common "subjects" that a lot of different users post on, and you want to present allt he posts on a subject, then my guess it will be a lot easier to put all your posts inside a single collection, rather than having to search multiple users collections to pull together all users' posts on a single subject. (Although that is not so hard really anymore either with the ability to search across multiple collecitons in a single query)
By the way, one thing to consider for a second is whether it makes any sense to put all the posts for a user inside of a single document if cost is a concern. If you do that you get all the posts in one document read and firestore charges are largely driven by docuemnt reads. However if you have to pull together posts from many users on a "subject", or if you have "threads" with posts from several different users this will approach will likely be impractical.
In response to your comment: Let's make sure we are using the same terminology. A thread is multiple posts from a number of different users on a single subject (i.e. posts and various replies). So if you have a set of users, and you are interested in seeing all posts they originated, you could keep a ThreadPosts collection, which has the originator of the thread and each post in a thread would contain a the ThreadPost, you could get a filtered collection of threads which the favorite user originated, and then you could get the posts for threads using methods like the below.
If you want to list all the threads which a favorite participated in then you would get all the posts from the favorite user, dedupe list of threadIds, and then pull in all the posts on that threadId in creationTimestamp order. You can use methods of firestore to get these collections both filtered by a field value (say, "threadId") and ordered by a fieldvalue (say, "creationTimestamp"). Here's some code (AngularFirestore in typescript) which demonstrates more or less what I mean.
interface ThreadPost {
id: string; //this is the id for this thread.
title : string;
originalAuthorId: string;
creationTimestamp : number;
lastUpdatedTimestamp: number;
}
and then your posts Collection also at the root, might look like:
[Typescript]
interface Post {
id: string;
authorId : string
threadId : string
postTest: string;
creationTimestamp: number;
lastUpdatedTimestamp: number;
}
So at the root of your db, you have 3 collections:
Users Posts PostThreads
So if you want to the all the posts from a user in createTimestamp order, you would do something like:
async fetchPosts(userId) : Post[] {
return getFilteredOrderedCollection("posts", "userId", ${userId}, "creationTimeStamp")
}
async getFilteredOrderedCollection(collectionPath : string, filterField : string,
filterValue: string, orderByField: string) : any[] {
let result: any[] = [];
await AngularFirestore.collection(`${collectionPath}`).ref
.where(`${filterField}`, "==", `${filterValue}`)
.orderBy(orderByField).get()
.then(function (snapshot) {
snapshot.forEach(function (doc) {
let p = doc.data()
p.timestamp = Date.now();
result.push(p)
})
})
return result;
}
And if you wanted all the posts on a thread you could call:
async fetchThreadPosts(threadId) : Post[] {
return getFilteredOrderedCollection("posts", "threadId", ${threadId},
"creationTimeStamp")
}