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

标签 java android firebase async-await

我试图从监听器 A 中从 Firebase 获取一些数据,然后我将根据从监听器 A 获取的某些 ID 在监听器 B 的不同节点下进行搜索,当我从监听器 B 接收到数据时,我想追加将其发送给监听器 A 数据。 基本上我在 Firebase 中有 2 个节点:帖子和用户。帖子有一些数据和用户 ID。当我想显示数据库中的所有帖子时,我将每个帖子添加到 RecyclerView 中,但在将它们添加到该 View 之前,我需要获取一些用户数据,然后(合并这 2 个收集到的数据)将其添加到 recyclerView 中.

我在网上找不到任何可以尝试的东西(除了一些 UI 阻塞的东西,我宁愿远离这些东西,因为我是 Android 新手)。我知道 Firebase 是异步的,而 Java 没有 Promises 或 async/await,所以我不知道还能尝试什么。通过我当前的实现,我没有实现我想要的(显然)。

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

最佳答案

I expect to display new data, data from user combined with the post.

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

关于java - 如何在 Firebase-Android 中链接 2 个事件监听器,以便第一个事件监听器在第二个事件监听器完成之前不会继续?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54152860/

相关文章:

java - 使用 JNDI 在 Tomcat 中共享 servlet session 对象和数据

Android使用requestLocationUpdates()时如何从intent获取信息

android - 应用程序在 android 中被杀死后后台服务不工作

firebase - 使用 Flutter 向 Cloud Firestore 添加对象

java - java中有线程安全且元素唯一的队列吗?

java - 在while循环中查找最大整数和最小整数

android - Firebase Crashlytics 没有为发布 apk 上传崩溃

javascript - Firebase实时数据库+JS对象

java - 将 XML 文件传递​​到 Web 服务

Android,日文字 rune 件名比较问题