DatabaseException: Expected a List while deserializing, but got a class java.util.HashMap

huangapple go评论109阅读模式
英文:

DatabaseException: Expected a List while deserializing, but got a class java.util.HashMap

问题

我正在为一个教育学院的应用程序工作,以下代码片段检索先前推送到 Firebase 实时数据库以与学生对象关联的父对象,然后再将此学生对象推送到数据库中。

如果这是特定父对象的第一个学生(子对象),则代码可以正常工作。
换句话说,这个父对象有一个 List 表示他的孩子。如果这个列表为空或为null,代码也可以正常工作。但是,如果要推送的学生是同一个父对象的第二个子对象,这意味着检索到的父对象将包含一个子对象列表,我会得到这个错误:

com.google.firebase.database.DatabaseException: 在反序列化时期望一个 List,但得到了一个 java.util.HashMap 类型的对象

这是检索父对象的方法:

private void getCorrespondingParent(){
    DatabaseReference correspondingParentReference = FirebaseDatabase.getInstance().getReference()
            .child("parents").child(mUserPhone);
    correspondingParentReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            mParent = snapshot.getValue(Parent.class);
            // 将 children 字段设为 null,因为父对象将保存在学生对象中,
            // 这样可以避免父对象有一个包含每个学生对象的孩子列表,
            // 而每个学生对象又有一个包含父对象的学生列表...
            mParent.setChildren(null);
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Log.w(LOG_TAG, "loadPost:onCancelled", error.toException());
        }
    });
}

数据库中的数据在获取 dataSnapshot 值的那一行:
mParent = snapshot.getValue(Parent.class);

这是数据库中的 Parent 节点:
DatabaseReference

这是 Parent 对象的 POJO 类:

public class Parent {
    private int accType;
    private String name;
    private String uid;
    private String phone;
    private String whatsappPhone;
    private String know;
    private List<Student> children;

    public Parent() {}

    public Parent(String name, String uid, String phone, String whatsappPhone, String know) {
        this.accType = 3;
        this.name = name;
        this.uid = uid;
        this.phone = phone;
        this.whatsappPhone = whatsappPhone;
        this.know = know;
    }

    // 各个属性的 getter 和 setter 方法...

    public List<Student> getChildren() {
        return children;
    }

    public void setChildren(List<Student> children) {
        this.children = children;
    }
}
英文:

I'm working on an app for an educational academy, the following snippet of code retrieves a Parent object that was previously pushed to Firebase Realtime Database to be linked to a Student object before this Student object is pushed to the database too..

If this is the first student (child) to this particular parent, the code works fine..
In other words, this Parent object has an List<Student> of his child(ren). If this list is empty or null, the code works fine.. but if the Student to be pushed is a second child to the same parent, which means the retrieved Parent object will contain a list of children, I get this:

com.google.firebase.database.DatabaseException: Expected a List while deserializing, but got a class java.util.HashMap

Here's the method that retrieves the Parent object:

private void getCorrespondingParent(){
    DatabaseReference correspondingParentReference = FirebaseDatabase.getInstance().getReference()
            .child(&quot;parents&quot;).child(mUserPhone);
    correspondingParentReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            mParent = snapshot.getValue(Parent.class);
            // null out the children field because the Parent object will be saved in the Student object
            // this avoids having a parent with children list that each Student in it has a parent object that
            // has a list of students...
            mParent.setChildren(null);
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Log.w(LOG_TAG, &quot;loadPost:onCancelled&quot;, error.toException());
        }
    });
}

the database is in the line that gets the value of the dataSnapshot:
mParent = snapshot.getValue(Parent.class);

here's the Parent node in the database:
DatabaseReference

and here's the POJO class for the Parent object:

public class Parent {
private int accType;
private String name;
private String uid;
private String phone;
private String whatsappPhone;
private String know;
private List&lt;Student&gt; children;

public Parent() {}

public Parent(String name, String uid, String phone, String whatsappPhone, String know) {
    this.accType = 3;
    this.name = name;
    this.uid = uid;
    this.phone = phone;
    this.whatsappPhone = whatsappPhone;
    this.know = know;
}

public int getAccType() {
    return accType;
}

public void setAccType(int accType) {
    this.accType = accType;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getUid() {
    return uid;
}

public void setUid(String uid) {
    this.uid = uid;
}

public String getPhone() {
    return phone;
}

public void setPhone(String phone) {
    this.phone = phone;
}

public String getWhatsappPhone() {
    return whatsappPhone;
}

public void setWhatsappPhone(String whatsappPhone) {
    this.whatsappPhone = whatsappPhone;
}

public String getKnow() {
    return know;
}

public void setKnow(String know) {
    this.know = know;
}

public List&lt;Student&gt; getChildren() {
    return children;
}

public void setChildren(List&lt;Student&gt; children) {
    this.children = children;
}

}

答案1

得分: 1

好的,我找到了问题所在。。

父对象节点中所示:

我使用学生姓名作为学生对象的键,还使用了List<Student>来存储父对象中的子项.. 结果发现,如果你在使用列表,不能为此目的使用自定义键,列表项键仅为其索引,且无法更改.. 我改为使用 Map&lt;String, Student&gt; children 代替 List&lt;Student&gt; children,现在它正常工作了。

在推送代码中不需要进行更改:

DatabaseReference newChildReference = FirebaseDatabase.getInstance().getReference()
            .child("parents").child(parentPhone).child("children").child(childKey);
    newChildReference.setValue(mNewStudent);
    newChildReference.push();

mNewStudent 是一个包含新添加的学生数据的 Student 对象。

英文:

Okay I found out what was the problem..

As shown in the Parent object node

I use student name as key to the Student object, and also used List<Student> to store the children of the parent in the Parent object.. turns out you can't use custom keys for that purpose if you're using a list, a list item key is it's index only and it can't be changed.. I switched to Map&lt;String, Student&gt; children instead of List&lt;Student&gt; children and now it works fine.

No changes needed in the code for pushing:

DatabaseReference newChildReference = FirebaseDatabase.getInstance().getReference()
            .child(&quot;parents&quot;).child(parentPhone).child(&quot;children&quot;).child(childKey);
    newChildReference.setValue(mNewStudent);
    newChildReference.push();

mNewStudent is a Student object that holds the newly added student data.

huangapple
  • 本文由 发表于 2020年10月24日 18:58:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/64512608.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定