如何使用 getValue(Subclass.class) 在 Firebase 中反序列化子类
How to deserialise a subclass in Firebase using getValue(Subclass.class)
我正在为 android 使用新的 firebase sdk 并使用真正的数据库功能。当我使用 getValue(simple.class)
时,一切都很好。但是当我想解析一个class是一个子class时,母亲class的所有属性都是null
,我有这种类型的错误:
No setter/field for name found on class uk.edume.edumeapp.TestChild
public class TestChild extends TestMother {
private String childAttribute;
public String getChildAttribute() {
return childAttribute;
}
}
public class TestMother {
protected String motherAttribute;
protected String getMotherAttribute() {
return motherAttribute;
}
}
这个函数
snapshot.getValue(TestChild.class);
motherAttribute
属性是 null
,我得到
No setter/field for motherAttribute found on class uk.edume.edumeapp.TestChild
我解析的Json是:
{
"childAttribute" : "attribute in child class",
"motherAttribute" : "attribute in mother class"
}
用于:
No setter/field for motherAttribute found on class uk.edume.edumeapp.TestChild
将 setter 用于 TestChild class:
public class TestMother {
private String motherAttribute;
public String getMotherAttribute() {
return motherAttribute;
}
//set
public void setMotherAttribute(String motherAttribute) {
this.motherAttribute= motherAttribute;
}
}
这里是 Firebaser
这是 Android 的某些版本的 Firebase 数据库 SDK 中的一个已知错误:我们的 serializer/deserializer 仅考虑声明的 class 上的 properties/fields。
Android 的 Firebase 数据库 SDK 9.0 至 9.6 (iirc) 版中缺少从基础 class 继承的属性的序列化。从那时起,它又被添加回了版本。
解决方法
同时,您可以使用 Jackson(Firebase 2.x SDK 在后台使用)使继承模型正常工作。
更新:这里有一个片段,说明如何从 JSON 读取 到您的 TestChild
:
public class TestParent {
protected String parentAttribute;
public String getParentAttribute() {
return parentAttribute;
}
}
public class TestChild extends TestParent {
private String childAttribute;
public String getChildAttribute() {
return childAttribute;
}
}
你会注意到我做了 getParentAttribute()
public,因为只考虑了 public fields/getters。有了这个改变,这个 JSON:
{
"childAttribute" : "child",
"parentAttribute" : "parent"
}
变得可读:
ObjectMapper mapper = new ObjectMapper();
GenericTypeIndicator<Map<String,Object>> indicator = new GenericTypeIndicator<Map<String, Object>>() {};
TestChild value = mapper.convertValue(dataSnapshot.getValue(indicator), TestChild.class);
这个GenericTypeIndicator
有点奇怪,还好是个神奇的咒语,可以copy/pasted。
勾选这个https://firebase.google.com/support/guides/firebase-android
它说
"If there is an extra property in your JSON that is not in your Java class, you will see this warning in the log files: W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage
"
Blockquote
您可以通过在 class 上添加 @IgnoreExtraProperties 注释来消除此警告。如果您希望 Firebase 数据库的行为与在 2.x SDK 中一样,并在存在未知属性时抛出异常,您可以在 class.
上添加 @ThrowOnExtraProperties 注释
Blockquote
这显然最终在 release 9.6 中得到修复。
Fixed an issue where passing a derived class to DatabaseReference#setValue() did not correctly save the properties from the superclass.
我正在为 android 使用新的 firebase sdk 并使用真正的数据库功能。当我使用 getValue(simple.class)
时,一切都很好。但是当我想解析一个class是一个子class时,母亲class的所有属性都是null
,我有这种类型的错误:
No setter/field for name found on class uk.edume.edumeapp.TestChild
public class TestChild extends TestMother {
private String childAttribute;
public String getChildAttribute() {
return childAttribute;
}
}
public class TestMother {
protected String motherAttribute;
protected String getMotherAttribute() {
return motherAttribute;
}
}
这个函数
snapshot.getValue(TestChild.class);
motherAttribute
属性是 null
,我得到
No setter/field for motherAttribute found on class uk.edume.edumeapp.TestChild
我解析的Json是:
{
"childAttribute" : "attribute in child class",
"motherAttribute" : "attribute in mother class"
}
用于:
No setter/field for motherAttribute found on class uk.edume.edumeapp.TestChild
将 setter 用于 TestChild class:
public class TestMother {
private String motherAttribute;
public String getMotherAttribute() {
return motherAttribute;
}
//set
public void setMotherAttribute(String motherAttribute) {
this.motherAttribute= motherAttribute;
}
}
这里是 Firebaser
这是 Android 的某些版本的 Firebase 数据库 SDK 中的一个已知错误:我们的 serializer/deserializer 仅考虑声明的 class 上的 properties/fields。
Android 的 Firebase 数据库 SDK 9.0 至 9.6 (iirc) 版中缺少从基础 class 继承的属性的序列化。从那时起,它又被添加回了版本。
解决方法
同时,您可以使用 Jackson(Firebase 2.x SDK 在后台使用)使继承模型正常工作。
更新:这里有一个片段,说明如何从 JSON 读取 到您的 TestChild
:
public class TestParent {
protected String parentAttribute;
public String getParentAttribute() {
return parentAttribute;
}
}
public class TestChild extends TestParent {
private String childAttribute;
public String getChildAttribute() {
return childAttribute;
}
}
你会注意到我做了 getParentAttribute()
public,因为只考虑了 public fields/getters。有了这个改变,这个 JSON:
{
"childAttribute" : "child",
"parentAttribute" : "parent"
}
变得可读:
ObjectMapper mapper = new ObjectMapper();
GenericTypeIndicator<Map<String,Object>> indicator = new GenericTypeIndicator<Map<String, Object>>() {};
TestChild value = mapper.convertValue(dataSnapshot.getValue(indicator), TestChild.class);
这个GenericTypeIndicator
有点奇怪,还好是个神奇的咒语,可以copy/pasted。
勾选这个https://firebase.google.com/support/guides/firebase-android
它说
"If there is an extra property in your JSON that is not in your Java class, you will see this warning in the log files: W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage "
Blockquote
您可以通过在 class 上添加 @IgnoreExtraProperties 注释来消除此警告。如果您希望 Firebase 数据库的行为与在 2.x SDK 中一样,并在存在未知属性时抛出异常,您可以在 class.
上添加 @ThrowOnExtraProperties 注释Blockquote
这显然最终在 release 9.6 中得到修复。
Fixed an issue where passing a derived class to DatabaseReference#setValue() did not correctly save the properties from the superclass.