2

I have a List<String> of names referring to Documents that I want to retrieve from FireStore. I want to access the contents after they are finished loading so I have implemented an OnCompleteListener in the Fragment that uses the data. However, I am not sure how to run a loop within a Task to query FireStore for each Document. I am querying FireStore in a Repository class that returns a Task object back through my ViewModel and finally to my Fragment. I want the Repository to return a Task so that I can attach an OnCompleteListener to it in order to know when I have finished loading my data.

My Repository Query method:

public Task<List<GroupBase>> getGroups(List<String> myGroupTags){
    final List<GroupBase> myGroups = new ArrayList<>();
    for(String groupTag : myGroupTags){
        groupCollection.document(groupTag).get()
                .addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                        if(task.isSuccessful()){
                            myGroups.add(task.getResult().toObject(GroupBase.class));
                        }
                    }
                });
    }
    return null; //Ignore this for now.
}

I know this won't return what I need but I am not sure how to structure a Task that incorporates a loop inside of it. Would I need to extract the contents of the List<String> in my Fragment and run individual queries for each item?

Any suggestions would be greatly appreciated.

Raymond Nguyen
  • 65
  • 2
  • 10
  • So what do you actually need, to transform a list of string into a list of Tasks? – Alex Mamo Feb 01 '19 at 16:35
  • 1
    It will be easier if you collect a bunch of Task objects and wait for them all to complete with Tasks.whenAll() to get a single Task with all the results. – Doug Stevenson Feb 01 '19 at 18:07
  • @AlexMamo essentially yes. I have a List of Document names and I need to transform this to essentially a List of Tasks to retrieve the entire document. Hi Doug, so you're suggesting I iterate through the list and for each item construct a Task and append the individual task to a new list? – Raymond Nguyen Feb 01 '19 at 18:33

1 Answers1

1

According to your comment:

I have a List of Document names and I need to transform this to essentially a List of Tasks to retrieve the entire document.

To solve this, please use the following lines of code:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference collRef = rootRef.collection("yourCollection");
List<String> myGroupTags = new ArrayList<>();
List<DocumentReference> listDocRef = new ArrayList<>();
for(String s : myGroupTags) {
    DocumentReference docRef = collRef.document(s);
    listDocRef.add(docRef);
}

List<Task<DocumentSnapshot>> tasks = new ArrayList<>();
for (DocumentReference documentReference : listDocRef) {
    Task<DocumentSnapshot> documentSnapshotTask = documentReference.get();
    tasks.add(documentSnapshotTask);
}
Tasks.whenAllSuccess(tasks).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
    @Override
    public void onSuccess(List<Object> list) {
        //Do what you need to do with your list
        for (Object object : list) {
            GroupBase gb = ((DocumentSnapshot) object).toObject(GroupBase.class);
            Log.d("TAG", tp.getPropertyname);
        }
    }
});
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Does initializing Task execute it? I don't kow why, but I feel like the get() method just executes it no matter what. Is this the case? – Jakub Kostka Oct 10 '19 at 06:39
  • @JakubKostka I'm afraid I did not understand you but please post another fresh question using its own [MCVE](https://stackoverflow.com/help/mcve), so me and other Firebase developers can help you. – Alex Mamo Oct 10 '19 at 07:49