1

So I have Activities documents in several Days collections and I need to combine all of the Activities in a list. I thought I should loop the collections and then loop the Activities and ended up with the code below which I don't know whether it's the best way to combine multiple collections. Even worse I don't know WHEN my list is ready to be used with all the asynchronous calls. Any advice? Thanks!

db.collection("calendar").get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    for (DocumentSnapshot ds : task.getResult().getDocuments()) {
                        ds.getReference().collection("thingstodo").get()
                                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                    @Override
                                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                                        for (DocumentSnapshot ds : task.getResult().getDocuments()) {
                                            ScheduledItem item = ds.toObject(ScheduledItem.class);
                                            itemsList.add(item);
                                        }

                                    }
                                });

                    }
            }
        });

2 Answers 2

3

The get() method you're using on CollectionReference (which is a subclass of Query) returns a Task that becomes resolved when the document is ready. Instead of adding a listener to that individual Task, collect all the tasks into a List, and pass that to Tasks.whenAllComplete() to respond when the entire set is complete. You can then examine the results of all the tasks there, as needed.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for that, Taskmaster! :) but this is too advanced for me. Would you mind pointing out to some example? Thanks
do you mean by using .get().getResult()? Can I build a task with this QuerySnapshot? What about the nested CollectionReference?
3

Managed to code what @Doug had suggested. Thanks taskmaster! This is so much better:

db.collection("calendar").get()
    .continueWith(new Continuation<Task<QuerySnapshot>, Task<?>>() {
        @Override
        public Task<?> then(@NonNull Task<Task<QuerySnapshot>> task) throws Exception {
            List<Task<QuerySnapshot>> tasks = new ArrayList<Task<QuerySnapshot>>();
            for (DocumentSnapshot ds : task.getResult().getResult())
                tasks.add(ds.getReference().collection("thingstodo").get());

            return Tasks.whenAllSuccess(tasks);
        }
    })
    .addOnCompleteListener(new OnCompleteListener<Task<?>>() {
        @Override
        public void onComplete(@NonNull Task<Task<?>> task) {
            List<QuerySnapshot> lists = (ArrayList<QuerySnapshot>)task.getResult().getResult();
            for (QuerySnapshot qs : lists)
                for (DocumentSnapshot ds: qs) {
                    ScheduledItem item = ds.toObject(ScheduledItem.class);
                    //add to list including day
                    itemsList.add(item);

                }

            //list ready to be used!
        }
    });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.