java - 使用 firebase recyclerview 始终返回最后一个值

标签 java android firebase firebase-realtime-database android-recyclerview

我的 firebase recyclerview 始终仅返回最后一个值。 我想在回收器 View 中显示用户名,所以我使用了查询。

这是我尝试过的

如果我选择“匈牙利”,找到 TripInfo-Hungary 节点并带上用户的 ID。 接下来,使用从匈牙利带来的方式在用户节点中查找。

我想要得到的类似于这个sql。 从 Tripinfo 选择用户 ID,其中国家='匈牙利' Tripinfo.userID=User.userID 上的内连接用户。

这是我的代码。

***Firebase realtime DB

tkitaka
  ㄴTripInfo
    ㄴHungary
      ㄴuserID1(D223Hlk5aMf17Su9rB9NeKEaT2c2)
      ㄴuserID2(dirrk65x0GTEQ8zlRYZNryqrGYH2)
      ㄴuserID2(shngJIzT8ieI1LiQ012peMHH5p13)

  ㄴUser
    ㄴuserID1(D223Hlk5aMf17Su9rB9NeKEaT2c2)
      ㄴuserName: aaa
    ㄴuserID2(dirrk65x0GTEQ8zlRYZNryqrGYH2)
      ㄴuserName: bbb
    ㄴuserID3(shngJIzT8ieI1LiQ012peMHH5p13)
      ㄴuserName: ccc
List<User> UserList;

...onCreateView...{

Query query2 = database.getReference().child("TripInfo").child(uCodeID);
query2.addValueEventListener(valueEventListener2);

}




ValueEventListener valueEventListener2 = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()){
                for (DataSnapshot snapshot: dataSnapshot.getChildren()){
                    TripInfo tripInfo = snapshot.getValue(TripInfo.class); 
                    userID = tripInfo.getUserID();
                    Log.d(TAG, "1일치유저★userID    "+userID); 

                    DatabaseReference UserRef = database.getReference().child("User");
                    UserRef.addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                            if (dataSnapshot.exists()){
                                for(DataSnapshot snapshot: dataSnapshot.getChildren()){
                                    String who = dataSnapshot.child(userID).child("userID").getValue().toString();
                                    UserList.clear();
                                    User user = snapshot.getValue(User.class);
                                    String a = user.getUserID();

                                    UserList.add(user);

                                    Log.d(TAG, "2유저리퍼★who    "+who);
                                }
                            }
                            tripSearchAdapter2.notifyDataSetChanged();
                        }

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

                        }
                    });
                }
            }
        }

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

        }
    };


我打印了日志,得到了这个。

D/여행정보검색: 1일치유저★userID    D223Hlk5aMf17Su9rB9NeKEaT2c2  (userID1)
D/여행정보검색: 1일치유저★userID    dirrk65x0GTEQ8zlRYZNryqrGYH2  (userID2)
D/여행정보검색: 1일치유저★userID    shngJIzT8ieI1LiQ012peMHH5p13  (userID3)
/// These are correct values that I want. 



D/여행정보검색: 2유저리퍼★who    shngJIzT8ieI1LiQ012peMHH5p13  (userID3)
I/chatty: uid=10085(com.example.tkitaka_fb) identical 16 lines
D/여행정보검색: 2유저리퍼★who    shngJIzT8ieI1LiQ012peMHH5p13
/// But here, I just got 1. Even it is last value of userID.

我认为我使用了错误的 for-loop 或 datasnapshot。我应该怎么做才能获得正确的代码?

最佳答案

你的嵌套监听器不断清除UserList对于它找到的每个用户:

UserList.clear();
User user = snapshot.getValue(User.class);
String a = user.getUserID();

UserList.add(user);

对所有用户执行此操作后,您最终会得到一个仅包含最后一个用户的列表。

总的来说,您的代码似乎关闭了,因为您正在为您加载的每次行程加载所有用户。更糟糕的是:你使用 addValueListener ,这意味着如果任何用户发生更改,您将在每次行程中重新加载所有用户。这不仅非常浪费,而且可能是错误的。

更典型/惯用的做法是仅加载每次行程的用户(因此 JSON 树中的下一级),并使用 addListenerForSingleValueEvent (这将加载一次数据,然后停止监听)。

所以类似:

DatabaseReference UserRef = database.getReference().child("User").child(userID);
UserRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        if (dataSnapshot.exists()){
            User user = snapshot.getValue(User.class);
            String a = user.getUserID();

            UserList.add(user);

            Log.d(TAG, "2유저리퍼★who    "+a);
        }
        tripSearchAdapter2.notifyDataSetChanged();
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException();
    }
});

您的代码与此之间的更改:

  • 传入userIDUserRef路径,以便您只加载当前行程的用户的数据。
  • 删除 for(DataSnapshot snapshot: dataSnapshot.getChildren())因为我们只加载单个用户。
  • 删除 String who = dataSnapshot.child("userID").getValue().toString() ,因为 userID 中已经具有相同的值.
  • 删除 UserList.clear(); ,否则您将在加载每个用户后清除用户列表。
  • 实现您的onCancelled ,因为忽略错误从来都不是一个好主意。

关于java - 使用 firebase recyclerview 始终返回最后一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58303588/

相关文章:

push-notification - firebase 是否处理推送通知?

java - 将数组放入文件列column

java - DocumentBuilder.parse 引发错误 "The prefix "c“元素 "c:de"未绑定(bind)。”

使用 FreeMarker 通过 Smooks 进行 Java 到 XML (SOAP)

java - Android到服务器的AES加密/解密

android - 在libGDX中绘制线条动画

android - E/AndroidRuntime:致命异常 : AsyncTask #2

java - 即使我使用的是默认已经支持maven的eclipse juno版本,是否有必要在linux环境中安装maven?

android - 使用 FCM 进行 ANR 并使用 applicationIdSuffix 构建变体

Firebase 安全规则遍历数据库进行验证