Reputation: 176
I am developing an activity that displays the posts of the users that the user follows. For the posts I used the following structure:
root --- posts (collection)
|
--- uid (documents)
|
--- userPosts (collection)
|
--- postId (documents)
| |
| --- title: "Post Title"
| |
| --- date: 4/06/2021
|
--- postId (documents)
|
--- title: "Post Title"
|
--- date: 08/06/2021
|
--- description: "this is the description of the post"
[...etc]
Lately I did an activity that visualized the posts of a user and that's it. Now, instead, I want to show the posts of the users that the user follows in the home page. This is the structure of the "following": posts (collection)
root--- folowing(documents)
|
--- uid(collection)
|
--- userFollowing(documents)
|
--- followed user(collection) -- followed user(document)
|
--- followed user (collection) -- followed user(document)
So, I tried to collect on an Arraylist all user uids that are followed by the user in this way:
FirebaseFirestore.getInstance().collection("following").document(FirebaseAuth.getInstance().getCurrentUser().getUid()).collection("userFollowing").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
document.getData();
Uidrecord.add(cont,String.valueOf(document.getData()));
cont++;
}
int conta = 0;
for (String item: Uidrecord){
if(item == null)
break;
uidFollowing.add(conta,getFollowingUid(item));
Toast.makeText(MainActivity.this, uidFollowing.get(conta), Toast.LENGTH_SHORT).show();
conta++;
}
} else {
Toast.makeText(MainActivity.this, task.getException().toString(), Toast.LENGTH_SHORT).show();
}
}
});
(uid Following contains all the ids of a user) This is how I set up the query to fetch a single user's post data:
Query query = FirebaseFirestore.getInstance()
.collection("post/" + uidVisit + "/userPosts")
.limit(1000);
I knew the user id I had to look for posts in, so it was a static query because I had to get a user's posts and that's it. Now instead the uid where to get the posts are contained in an arraylist. So I was wondering how I could create a dynamic query and then how to grab the posts of every single user followed (using RecyclerView). It's possible to do it?
Edit: As you can see from my complete code https://codeshare.io/MNWYb3 I tried putting a for (line 225) and dynamizing the query, but the result is that it only shows the posts of a user and that's it (seems to override each for the adapter, in fact the post shown is the last person followed so the last arraylist item)
Upvotes: 2
Views: 342
Reputation: 5829
With your current structure on Firestore this is going to be a bit difficult, I think you should first simplify your structure, I would suggest you keep a structure like this:
users
|
--- uid : "uid1"
name: "John Doe"
...
usersFollowed : [uid1, uid2, ..., uidn]
userPosts (collection)
|
--- uid: "uuid1"
title: "Post Title"
date: 08/06/2021
description: "this is the description of the post"
userId: "uid1"
....
With this you are only operating on a single collection and a it's subcollection, which lowers complexity a bit, you would be storing the list of users that each user follows in the usersFollowed
array field of each user document.
Up next you could iterate the list of usersFollowed
randomly:
List<String> listOfFollowed = new ArrayList<>();
// userDocument is your current user
listOfFollowed = userDocument.get(usersFollowed);
Collections.shuffle(listOfFollowed);
List<DocumentSnaphot> listOfPosts = new ArrayList<DocumentSnaphot>();
for (String item : listOfFollowed) {
Query query = FirebaseFirestore.getInstance()
.collection("users")
.document(userDocument.getId())
.collection("userPosts")
.document(item)
.orderBy("date")
.limit(1);
listOfPosts.add(query.get().getDocument().get(0));
}
This code is going to give you the single latest post of each user that is followed by the current user in a random order.
It's not a dinamic query, but it will be giving you random results, and you can tweek the logic behind how many post from each users you want to get at first, or create a function that is triggered and gets more post when the user has seen all the ones you already fetched and so on.
EDIT
Checking your complete code I came to the conclusion that the issue you are facing is related to the use of a FirestoreRecyclerAdapter
, which expects a query as a parameter, however, your use case requires you to execute your query over and over again in a loop to get the results. Passing that same query as an option for the FirestoreRecyclerAdapter
will result on you getting a query that only get the last userFollowed
in your list, as this will be it's final iteration in the loop and will be what is moved forward in the app's execution, which is not the expected result.
So instead of using a FirestoreRecyclerAdapter
I would recommend you to use a ListAdapter
, which expects a List as a parameter. The list you will use as this parameter will be a new list that is populated with the results of your query being executed over and over in that loop you created.
That being said, I would recommend you to take a look at that documentation and see what other changes this might imply in your code since you will be changing the type of class you are using and this might have unexpected consequences. Also this tutorial might help.
Upvotes: 1