Android Firestore convert array of document references to List<Pojo>

In my Firestore I've got a users collection, within which the documents could have a bookmarks field, which is an array of references:

Firestore bookmarks example

Each of these references points to a document in the teachers collection:

Teacher example

In my Android app, I want to create a method getBookmarks which returns a List of POJOs each of which represents a teacher. This is what I coded, but I think there are two problems:

  1. I can't return a List<TeacherPojo> to my callback, because I'm getting each document reference singularly
  2. I think that attaching a callback for every item in a collection (which size it's user controlled, a user can have as many bookmarks as he/she wants) could have a high impact on performances.

    public void getBookmarks(@NonNull OnSuccessListener<List<TeacherPojo>> callback) 
    {
        checkNotNull(callback);
    
        // document reference points to the user document which is calling this method
        documentReference.get()
            .addOnSuccessListener((documentSnapshot) -> {
                ArrayList<DocumentReference> teacherReferences = (ArrayList<DocumentReference>) documentSnapshot.get("bookmarks");
    
                Iterables.forEach(teacherReferences, (documentReference) -> {
                documentReference.get()
                    .addOnSuccessListener((teacherSnapshot) -> {
                    TeacherPojo teacherPojo = teacherSnapshot.toObject(TeacherPojo.class);
    
                        // now?
                    });
                });
            });
    }
    

Is there a better way to code this method, in order to get a List<TeacherPojo> (and possibly without having too impact on performances)?


Solution 1:

Yes it is. Please see the following lines of code:

FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
if (firebaseUser != null) {
    String uid = firebaseUser.getUid();
    rootRef.collection("users").document(uid).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()) {
                DocumentSnapshot document = task.getResult();
                if (document.exists()) {
                    List<DocumentReference> list = (List<DocumentReference>) document.get("bookmarks");
                    List<Task<DocumentSnapshot>> tasks = new ArrayList<>();
                    for (DocumentReference documentReference : list) {
                        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) {
                                TeacherPojo tp = ((DocumentSnapshot) object).toObject(TeacherPojo.class);
                                Log.d("TAG", tp.getFirstName());
                            }
                        }
                    });
                }
            }
        }
    });
}

So the List<Object> list is actually the list that contains objects of type TeacherPojo.