Ожидание потоков в android java

Работаю с firebase, появилась задача ожидать завершения потоков, но реализация хромает.

У меня структура такая : обращаюсь по пути N получаю массив клиентов (id), этот массив клиентов так же содержит массив информации, который хранится по пути M, обращаюсь M, получаю информацию, записываю.

Проблема в том, что получение информации по пути M происходит асинхронно и мне нужно дождаться ответа. Я такое реализовал в ios с помощью dispatchgroup, на andoroid попытался использовать CountDownLatch, но либо я что-то не так делаю, либо он сюда не подходит. Моя попытка :

   void getClients(){
        DatabaseReference ref = dataFirebase.scheduleReference.child(dataFirebase.currentId).child("list");
        ref.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
                    Map<String,Object> users =  (HashMap<String, Object>) postSnapshot.getValue();

                    getUserInfo(users, new ResultHandler<ArrayList<SectionData>>() {
                        @Override
                        public void onSuccess(ArrayList<SectionData> data) {
                           // to-do
                        }

                    });
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                System.out.println("The read failed: " + databaseError.getCode());
            }
        });
    }


   void getUserInfo(final Map<String,Object> users,  final ResultHandler<ArrayList<SectionData>> handler){
        final ArrayList<SectionData> sdata = new ArrayList<SectionData>();
        final CountDownLatch cdl1 = new CountDownLatch(users.keySet().toArray().length);

        for(Map.Entry<String, Object> entry : users.entrySet()) {
            String uid = entry.getKey();
            final Map<String, Object> value = (HashMap<String, Object>) entry.getValue();

            dataFirebase.getInfoAboutUID(uid, new ResultHandler<AUser>() { // обращение к firebase
                @Override
                public void onSuccess(AUser newUser) {
                  // to-do with sdata and newUser
                   // handler.onSuccess(sdata);
                    cdl1.countDown();
                }

            });
        }

        try {
            cdl1.await();

            handler.onSuccess(sdata);
        } catch(InterruptedException exc) { }


    }

Ответы (1 шт):

Автор решения: Roman Konoval

Сейчас вызов getUserInfo происходит из потока, который обслуживает события от firebase. И пока вызов onDataChange не закончится поток занят и поэтому новые события не будут обрабатываться. Получается deadlock и вызов ResultHandler, в котором сейчас cdl1.countDown() вызывается, в принципе не происходит.

Нужно вызывать hanlder напрямую:

dataFirebase.getInfoAboutUID(uid, new ResultHandler<AUser>() { // обращение к firebase
  @Override
  public void onSuccess(AUser newUser) {
    // нужно завернуть в Handler чтоб вызов onSuccess произошел в главном обработчике
    new Handler(Looper.getMainLooper()).post(() -> handler.onSuccess(sdata));
  }
});
→ Ссылка