1

I have a Posts collection in which each document has these fields userId, postImage, uploadTime ...

I want to fetch the information of the user (userName, userImage) from Users collection using the userId field of Posts collection and merge it with the PostModel


public class PostModel {

    private String userId;

    private String userName;

    private String userImage;

    private String postImage;

    private long likeCount;

    private long dislikeCount;

    private Timestamp uploadTime;

    public PostModel() {
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserImage() {
        return userImage;
    }

    public void setUserImage(String userImage) {
        this.userImage = userImage;
    }

    public String getPostImage() {
        return postImage;
    }

    public void setPostImage(String postImage) {
        this.postImage = postImage;
    }

    public long getLikeCount() {
        return likeCount;
    }

    public void setLikeCount(long likeCount) {
        this.likeCount = likeCount;
    }

    public long getDislikeCount() {
        return dislikeCount;
    }

    public void setDislikeCount(long dislikeCount) {
        this.dislikeCount = dislikeCount;
    }

    public Timestamp getUploadTime() {
        return uploadTime;
    }

    public void setUploadTime(Timestamp uploadTime) {
        this.uploadTime = uploadTime;
    }
}

Currently, this is how I am querying but I am not able to track if all the requests to fetch each Users document related to Posts completed?

seepakDatabase.collection(COLLECTION_POSTS).orderBy(SORT, Query.Direction.DESCENDING).limit(LIMIT).get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {

            @Override
            public void onSuccess(QuerySnapshot queryDocumentSnapshots) {

                // Clearing the previous data of the lists if any.
                postModelList.clear();

                if (queryDocumentSnapshots.getDocuments().size() < LIMIT) {

                    setNoMoreData(true);

                } else {

                    setNoMoreData(false);

                    lastDocumentSnapshot = queryDocumentSnapshots.getDocuments().get(queryDocumentSnapshots.size() - 1);

                }

                for (QueryDocumentSnapshot queryDocumentSnapshot : queryDocumentSnapshots) {

                    final PostModel postModel = queryDocumentSnapshot.toObject(PostModel.class);


                    String userId = postModel.getUserId();

                   // How to know if all the queries made here completed?

                    seepakDatabase.collection(COLLECTION_USERS).document(userId).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                        @Override
                        public void onSuccess(DocumentSnapshot documentSnapshot) {

                            postModel.setUserName(documentSnapshot.getString("userName"));

                            postModel.setUserImage(documentSnapshot.getString("userImage"));

                            postModelList.add(postModel);
                        }
                    });

                }

                // Hiding the swipe refresh progress bar if visible.
                postsSwipeRefresh.setRefreshing(false);

                // Hiding progress bar when lists populate if visible.
                postFetch.setVisibility(View.GONE);

                // Notifying adapter to load new data in recycler view.
                feedAdapter.notifyDataSetChanged();

            }
        });

Update 1


                List<Task<DocumentSnapshot>> tasks = new ArrayList<>();

                for (QueryDocumentSnapshot queryDocumentSnapshot : queryDocumentSnapshots) {

                    final PostModel postModel = queryDocumentSnapshot.toObject(PostModel.class);

                    Task<DocumentSnapshot> documentSnapshotTask = seepakDatabase.collection(COLLECTION_USERS).document(postModel.getUserId()).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                        @Override
                        public void onSuccess(DocumentSnapshot documentSnapshot) {
                            postModel.setUserName(documentSnapshot.getString("userName"));
                            postModel.setUserImage(documentSnapshot.getString("userImage"));

                            postModelList.add(postModel);
                        }
                    });

                    tasks.add(documentSnapshotTask);

                }

                Tasks.whenAllSuccess(tasks).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
                    @Override
                    public void onSuccess(List<Object> objects) {

                        // Hiding the swipe refresh progress bar if visible.
                        postsSwipeRefresh.setRefreshing(false);

                        // Hiding progress bar when lists populate if visible.
                        postFetch.setVisibility(View.GONE);

                        // Notifying adapter to load new data in recycler view.
                        feedAdapter.notifyDataSetChanged();

                    }
                });
Malik Bilal
  • 869
  • 8
  • 25

1 Answers1

1

Query's get() method returns a Task<QuerySnapshot> while DocumentReference's get() returns Task<DocumentSnapshot>. Because QueryDocumentSnapshot extends DocumentSnapshot, add the Task objects from every iteration to a list. In the end simply pass that list to Tasks's whenAllSuccess(Collection> tasks) method, as explained in my answer from the following post:

In this way, you'll know when you got all the documents.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193