英文:
DatabaseException: Expected a List while deserializing, but got a class java.util.HashMap
问题
我正在为一个教育学院的应用程序工作,以下代码片段检索先前推送到 Firebase 实时数据库以与学生对象关联的父对象,然后再将此学生对象推送到数据库中。
如果这是特定父对象的第一个学生(子对象),则代码可以正常工作。
换句话说,这个父对象有一个 List
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("parents").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, "loadPost:onCancelled", 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<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;
}
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<Student> getChildren() {
return children;
}
public void setChildren(List<Student> children) {
this.children = children;
}
}
答案1
得分: 1
好的,我找到了问题所在。。
如父对象节点中所示:
我使用学生姓名作为学生对象的键,还使用了List<Student>来存储父对象中的子项.. 结果发现,如果你在使用列表,不能为此目的使用自定义键,列表项键仅为其索引,且无法更改.. 我改为使用 Map<String, Student> children
代替 List<Student> 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<String, Student> children
instead of List<Student> children
and now it works fine.
No changes needed in the code for pushing:
DatabaseReference newChildReference = FirebaseDatabase.getInstance().getReference()
.child("parents").child(parentPhone).child("children").child(childKey);
newChildReference.setValue(mNewStudent);
newChildReference.push();
mNewStudent is a Student object that holds the newly added student data.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论