如何在Firebase-Android中链接2个事件监听器,以便第一个事件侦听器在第二个完成之前不会继续?



我正在尝试从侦听器 A 获取一些数据,然后我会根据从侦听器 A 获得的一些 ID 在侦听器 B 的不同节点下搜索侦听器 B,当我收到来自侦听器 B 的数据时,我想将其附加到侦听器 A 数据。基本上我在Firebase中有2个节点:帖子和用户。帖子有一些数据和用户 ID。当我想显示数据库中的所有帖子时,我将每个帖子添加到 RecyclerView,但在将它们添加到该视图之前,我需要获取一些用户数据,然后才(组合这两个收集的数据)将其添加到 recyclerView。

我在网上找不到任何可以尝试的东西(除了一些 UI 阻止的东西,因为我是 Android 新手,我宁愿远离)。我知道Firebase是异步的,Java没有Promise或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

我希望显示新数据,来自用户的数据与帖子相结合。

未获取新数据的原因是,在第二个侦听器中获取用户数据之前,您要向列表添加indivPost并通知第一个侦听器中的回收视图。这样你就无法实现你想要的,因为你的for loop是同步的,而侦听器是异步的。更改 Firebase 结构以将用户名与帖子一起存储,这样您就不必再次调用来获取用户名。

最新更新