Как связать 2 EventListeners в Firebase-Android, чтобы первый не продолжался до конца второго? - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь получить некоторые данные из Firebase от слушателя A, затем я буду искать в другом узле с слушателем B на основе некоторого идентификатора, полученного от слушателя A, и когда я получу данные от слушателя B, я хочу добавить это для слушателя данных. В основном у меня есть 2 узла в Firebase: посты и пользователи. В сообщении есть некоторые данные и идентификатор пользователя. Когда я хочу отобразить все записи в базе данных, я добавляю каждую в RecyclerView, но прежде чем добавить их в это представление, мне нужно получить некоторые пользовательские данные и только затем (объединяя эти 2 собранные данные) добавить их в recyclerView. .

Я не смог найти в Интернете ничего, чтобы попробовать (кроме некоторых вещей, блокирующих пользовательский интерфейс, которые я предпочитаю избегать, поскольку я новичок в Android). Я знаю, что Firebase является асинхронным, и что в Java нет Promises или async / await, так что IDK, что еще попробовать. С моей текущей реализацией я не достигаю того, чего хочу (очевидно).

private void initialPopulatePostsFromDB(){
        mDatabase.limitToFirst(2).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                List<IndividualPost> postsDB = new ArrayList<>();

                for(DataSnapshot postSnapShot : dataSnapshot.getChildren()){

 oldestPostId = postSnapShot.getKey();
                    final IndividualPost indivPost = postSnapShot.getValue(IndividualPost.class);
                    indivPost.setContents(typePostContents);

                    /*
                    FirebaseDatabase.getInstance().getReference("/users").child(indivPost.getUserId()).addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                            userAccount = dataSnapshot.getValue(UserAccount.class);

                            indivPost.setUserId(userAccount.getName());
                            System.out.println("[1] ACC NAME: " + indivPost.getUserId());
                        }
                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {

                        }
                    });
                    */

                    FirebaseDatabase.getInstance().getReference("/users").child(indivPost.getUserId()).addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                            userAccount = dataSnapshot.getValue(UserAccount.class);

                            indivPost.setUserId(userAccount.getName());
                            System.out.println("[1] ACC NAME: " + indivPost.getUserId());
                        }
                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {

                        }
                    });

                    System.out.println("[2] ACC NAME: " + indivPost.getUserId());
                    postsDB.add(indivPost);
                    System.out.println("[3] ACC NAME: " + indivPost.getUserId());
                }

                posts.addAll(postsDB);
                mAdapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

Я ожидаю отображения новых данных, данных пользователя и сообщения.

I expected to be printed:
[1] ACC NAME John
[2] ACC NAME John
[3] ACC NAME John
but it's actually 
[2] BniepYpQuh6VgMF6L2
[3] BniepYpQuh6VgMF6L2
[1] John

1 Ответ

0 голосов
/ 11 января 2019

Я ожидаю отображения новых данных, данных пользователя и сообщения.

Причина, по которой вы не получаете новые данные, заключается в том, что вы добавляете indivPost в список и уведомляете представление recycle в первом слушателе, прежде чем получать пользовательские данные во втором слушателе. Таким образом, вы не можете достичь того, чего хотите, потому что ваш for loop является синхронным, а слушатель асинхронным. Измените свою структуру Firebase, чтобы хранить имя пользователя с сообщениями, поэтому вам не нужно делать второй звонок, чтобы получить имена пользователей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...