Firebase / Android - Wait for all the thread for a Handle

0

I have the following code:

public synchronized void next(final RoomListQueryResultHandler handler) {
        this.setLoading(true);

        roomList = new ArrayList<Room>();
        this.database.child("members").child(this.mUser.getUid()).child("rooms")
                .limitToFirst(this.mLimit)
                .startAt(this.currentPage * this.mLimit)
                .addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        RoomListQuery.this.setLoading(false);
                        //mListAdapter.setLoading(false);

                        if (!dataSnapshot.hasChildren()) {
                            RoomListQuery.this.currentPage--;
                        }
                        for (DataSnapshot ds : dataSnapshot.getChildren()) {
                            Room room = ds.getValue(Room.class);
                            //roomList.add(Room.upsert(room));
                            Room.getRoom(room.getId(), new Room.RoomGetHandler() {
                                @Override
                                public void onResult(Room room, customException e) {
                                    if (e != null) {
                                        // Error!
                                        e.printStackTrace();
                                        return;
                                    }

                                    roomList.add(room);
                                }
                            });
                            handler.onResult(roomList, (customException) null);
                        }

                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                        handler.onResult((List) null, new customException(databaseError.toString()));
                    }
                });
    }
}

If they are fixed I have two Handler, at the beginning I call a list of "rooms" from Firebase, and then for each one I will check the detail.

The problem I have is that the answer gives it to me empty, since it does not wait for all the for for the detail of the "rooms" to be executed, for which the variable roomList always returns empty.

Any ideas that I can implement, or what other methodology can I use to solve it?

Thank you very much! Greetings.

============== Edito ============

I added an accountant to know when to make the callback.

public synchronized void next(String key,final RoomListQueryResultHandler handler) {

        this.setLoading(true);
        roomList = new ArrayList<Room>();
        this.database.child("members").child(this.mUser.getUid()).child("rooms")
                .orderByKey()
                .addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        RoomListQuery.this.setLoading(false);
                        if (!dataSnapshot.hasChildren()) {
                            RoomListQuery.this.currentPage--;
                        }

                        // at the start we need to still load all children
                        final long[] pendingLoadCount = { dataSnapshot.getChildrenCount() };

                        for (DataSnapshot ds : dataSnapshot.getChildren()) {
                            //roomList.add(Room.upsert(room));
                            Room.getRoom(ds.getKey(), new Room.RoomGetHandler() {
                                @Override
                                public void onResult(Room room, customException e) {
                                    if (e != null) {
                                        // Error!
                                        e.printStackTrace();
                                        return;
                                    }
                                    roomList.add(room);

                                    // we loaded a child, check if we're done
                                    pendingLoadCount[0] = pendingLoadCount[0] - 1;
                                    if (pendingLoadCount[0] == 0) {
                                        if (handler != null) {
                                            Friends.runOnUIThread(new Runnable() {
                                                public void run() {
                                                    handler.onResult(roomList, (customException) null);
                                                }
                                            });
                                        }
                                    }


                                }
                            });

                        }

                    }

                    @Override
                    public void onCancelled(final DatabaseError databaseError) {
                        if (handler != null) {
                            Friends.runOnUIThread(new Runnable() {
                                public void run() {
                                    handler.onResult((List) null, new customException(databaseError.toString()));
                                }
                            });
                        }
                    }
                });
    }
    
asked by Hack Crack 28.06.2017 в 02:32
source

2 answers

0

It is not entirely clear what Room.getRoom does and why not use the room that is stored in Firebase. But if what you want is to block the thread until all the queries are finished there are 2 alternatives:

1) If your task extends Task from Google Play Task API (recommended), you can use the Tasks.whenAll(<colección de tareas>) method, which locks the current thread until all the asynchronous tasks in the collection end (successfully or not).

2) If Room.getRoom is a task that can not incorporate the task API, you can choose CountDownLatch which is a standard Java class that has a counter and locks the thread until the counter reaches zero (you should decrement the counter each time a task completes).

    
answered by 03.07.2017 / 20:17
source
0

I do not really know how the process is going but I understand that you want to first get the list and then use that list in the handler.

What I would do would be to implement a callback so that when it finishes bringing all the information from the firebase it can "warn" the handler of the completion of the operation and you can be sure that the list will never be empty.

    
answered by 28.06.2017 в 13:10