繁体   English   中英

反序列化时需要一个列表,但得到了一个类 java.util.HashMap

[英]Expected a List while deserializing, but got a class java.util.HashMap

我正在尝试从 Android 中的 Firebase 获取用户列表。

在此处输入图像描述

我已经有了用户的 uuid,并使用它来尝试获取整个对象。 uuid 既是节点名又是用户节点内的字段(当然是一样的)。

这是我的代码:

DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("users");
Query query = usersRef.orderByChild("uuid").equalTo(animalMarker.getUserUid());
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Log.d(TAG, "onDataChange: xxxxxxxx---- entered onDataChange");

            // go to node "users/userUID" , becuase dataSnapshot is parent node
            for (DataSnapshot ds : dataSnapshot.getChildren()) {
                Log.d(TAG, "xxxxxxxx---- onDataChange: ds= " + ds);
                User user = ds.getValue(User.class);
                Log.d(TAG, "xxxxxxxx---- onDataChange: user=" + user);
                // createdByTV.setText("Created by \n" + user.getEmail());
            }

        }

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

        }
    });

我不知道错误“expected List but got HashMap”是来自整个 DataSnapshot 本身,还是来自用户内部的动物列表(用户类有一个字段 List animals)

我已经检查了这个类似的问题Andorid-Expected a List while deserializing,但是得到了一个类 java.util.HashMap和其他几个,但我仍然不明白哪里出了问题。

编辑:我正在尝试获取用户电子邮件,知道它的 ID(uuid)。 虽然获取整个 User 对象不是必需的,但我很好奇它是如何完成的,因为我无法做到其中任何一个。

编辑:这是我的用户类

public class User {

private String uuid;
private String email;
private String name;
private List<User> friends;
private List<Animal> animals;

public User() {
}

public User(String email, String name) {
    this.email = email;
    this.name = name;
}

public User(String uuid, String email, String name) {
    this.uuid = uuid;
    this.email = email;
    this.name = name;
}
... // getters and setters, toString and other such
}

当试图获取其中没有动物节点的用户时,一切正常。 但是当试图让用户在里面有动物节点时,应用程序崩溃了。

实际上,我回答了那个问题,但在这种情况下,问题有点不同。 所以你收到以下错误:

预期列表但得到 HashMap

因为存在于每个用户对象中的animals节点不是动物对象列表,实际上是动物对象的地图,这就是出现此错误的原因。

虽然获取整个 User 对象不是必需的,但我很好奇它是如何完成的,因为我无法做到其中任何一个。

没错,您只需使用以下代码行即可获取电子邮件地址:

String email = ds.child("email").getValue(String.class);

现在,要将DataSnapshot对象映射到User并从特定用户获取动物对象列表,请删除:

//private List<User> friends;
//private List<Animal> animals;

并使用以下代码行:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference animalsRef = rootRef.child("users").child(uid).child("animals");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<Animal> animalList = new ArrayList<>();
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            Animal animal = ds.getValue(Animal.class);
            animalList.add(animal);
        }

        //Do what you need to do with the animalList
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
    }
};
animalsRef.addListenerForSingleValueEvent(valueEventListener);

动物列表不在用户内部,而是在用户节点内部。 在任何情况下,将其置于用户对象内部似乎比需要的嵌套更多。 你应该有另一个节点的动物

user_animals:{
    uid:{key1:{}, key2:{}
}

您现在的问题是您正在查询而不是获取节点值

usersRef.child(uid).addSingleEvent..

...onDataChange...
User user = datasnapshot.getValue(User.class);

您需要创建一个用户类来反映 RTD 中的用户属性

构建树的方式是问题的根源。

就在今天,我在重构一个旧项目的 firebase 树时遇到了同样的错误,所以我在谷歌中查找错误并找到了这个页面,我注意到你的动物节点中的这 3 个用户属性看起来不合适。

所以我回到我的树,显然我在我的一个列表节点中错误地添加了一个键:值对,所以我删除了它们,一切都很好。

问题:

这是因为您有一个动物列表,并且在该列表中您有这 3 个键值(电子邮件、uuid、名称),这会混淆 firebase serilization,因此他试图将其转换为 hashmap

解决方案:

我认为如果您不解决它并按照以下方式操作,您将来会受益:3 个用户属性 email、name 和 uuid 应该包装在用户树内的不同节点中,比如 user_data 并且你应该有一个动物的不同节点将只有动物列表!

  • 用户
    • sfdasfasfasfasf
      • 用户数据
        • 电子邮件:“asdf”
        • 名称:“asdfas”
        • uuid:“dfqwtr4”
      • 动物
        • asdfaskdfjlasdgafd
          • 成人:“asdf”
          • 动物编号:“asdfas”
          • 动物名称:“dfqwtr
          • 大约年龄:“asdf”
          • 中性:“asdfas”
          • 图片链接:“dfqwtr”
        • sdafasfdasgasga
          • 成人:“asdf”
          • 动物编号:“asdfas”
          • 动物名称:“dfqwtr
          • 大约年龄:“asdf”
          • 中性:“asdfas”
          • 图片链接:“dfqwtr”

然后你的 pojo 应该看起来像:一个User类,具有UserDataList<Animal>的属性,具有相应的序列化名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM