Q:

Reduce number of read in Firestore Android

I want to reduce number of reads in order to get Question's detail from QuestionCollection (Array of Questions) .

My app works like a part of stackoverflow.
I want to show how many likes, views and comments do a question have . So in order to handle this I created multiple collection like
QuestionCollection 

ID
Title
DateCreated

CommentCollection

ID
Comment
DateCreated

QuestionLikes

QuestionID
UserID

QuestionViews

QuestionID
UserID

QuestionTAG

QuestionID
TagID

I thought that CommentCollection (comments) only belongs to a question. So I am thinking of incorporating in QuestionCollection like an array(s) or collection(But it requires another read hit). which one is better ?
And I think of adding two variable's(totalViews,totalLikes) to QuestionCollection. But each time I must have to check whether this question is liked by this user or view by this user.
Give me a suggestion or an alternative so I can have the least hit to fetch question details.
Edit
For Showing View Count 
    I iterate and count QuestionViews Collection where questionID  == myQuestionID
For Showing Likes Count 
    I iterate and count QuestionLikes Collection where questionID  == myQuestionID
why I don't add it to QuestionCollection? Because I want to show most Viewed and most like question like stackoverflow. If i add it to QuestionCollection How could I know the most like and most Viewed question.

A:

The most efficient schema I can think of, is the following:
Firestore-root
    |
    --- questions (collections)
    |     |
    |     --- questionId (document)
    |            |
    |            --- questionId: "02cubnmO1wqyz6yKg571"
    |            |
    |            --- title: "Question Title"
    |            |
    |            --- date: August 27, 2018 at 6:16:58 PM UTC+3
    |            |
    |            --- comments (colletion)
    |            |     |
    |            |     --- commentId
    |            |            |
    |            |            ---commentId: "5aoCfqt2w8N8jtQ53R8f"
    |            |            |
    |            |            ---comment: "My Comment"
    |            |            |
    |            |            ---date: August 27, 2018 at 6:18:28 PM UTC+3
    |            |
    |            --- likes (colletion)
    |            |     |
    |            |     --- likeId (document)
    |            |            |
    |            |            --- userId: true
    |            |
    |            --- views (colletion)
    |            |     |
    |            |     --- viewId (document)
    |            |            |
    |            |            --- userId: true
    |            |
    |            --- tags ["tagId", "tagId"]
    |
    --- tags (collections)
          |
          --- tagId (document)
                |
                --- tagId: "yR8iLzdBdylFkSzg1k4K"
                |
                --- tagName: "Tag Name"

In which the comments, likes and views are colletions under questionId document. Unlike in Firebase real-time database where to display a list of question you would have been downloaded the entire question object, in Cloud Firestore this is not an issue anymore. So to avoid querying using a where methods, you can simply get a specific question like this:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
DocumentReference questionIdRef = rootRef.collection("questions").document(questionId);
questionIdRef.get().addOnCompleteListener(/* ... */);

Because you can have hundreds, thousands or even more comments, likes and views to a single question, storing the data into an array will not help you. According to the official documentation:

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

For example, to get all the comments of a specific question, you can use the following query:
Query query = rootRef.collection("questions/"+questionId+"comments").orderBy("date", Query.Direction.DESCENDING);

Because a question can have only a few tags, you can simply use an array. To get all questions with a specific tag, you can use the following query:
Query query = rootRef.collection("questions/"+questionId+"tags").whereArrayContains("tags", tagId);

One more thing to remember, even if tags object is stored in the database as an array, document.get("tags") will return an ArrayList and not an array.
If you also want to count the number of likes or any other number of documents within a collection, please see my answer from this post.
Edit:
According to your comments:

If I want to show the most liked question of all to a user. How could I do this?

You should add the number of likes as a property inside the question object and then you can query the database according to it like this:
Query query = rootRef.collection("questions").orderBy("numberOfLikes", Query.Direction.DESCENDING);

According to this you can also store the number of likes in the Firebase real-time database and you can increase/decrease it using Firebase Transactions.

secondly if I want to show all the question related to a tag like mathematics (show all question which have mathematics tag) ??

As also mentioned above you can take atvantage of the whereArrayContains method. You can also store the tags as String and not as id. For that, you need to change this structure:
--- tags ["tagId", "tagId"]

to
--- tags ["mathematics", "chemistry"]

And the code should look like this:
Query query = rootRef.collection("questions/"+questionId+"tags").whereArrayContains("tags", "mathematics");

the statement (userId: true) saves a lot of data repetition

Yes it does.

