Как десериализовать подкласс в Firebase, используя getValue(Subclass.class)
Я использую новый Firebase SDK для Android и использую реальную функцию базы данных. Когда я использую getValue(simple.class)
Все отлично. Но когда я хочу проанализировать класс, который является подклассом, все атрибуты родительского класса null
и у меня есть этот тип ошибки:
Не найдено сеттера / поля для имени в классе 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
и я получаю
Не найден сеттер / поле для motherAttribute в классе uk.edume.edumeapp.TestChild
JSON, который я анализирую:
{
"childAttribute" : "attribute in child class",
"motherAttribute" : "attribute in mother class"
}
4 ответа
Firebaser здесь
Это известная ошибка в некоторых версиях Firebase Database SDK для Android: наш сериализатор / десериализатор рассматривает только свойства / поля в объявленном классе.
Сериализация унаследованных свойств базового класса отсутствует в выпусках 9.0–9.6 (iirc) пакета Firebase Database SDK для Android. С тех пор он был добавлен в версии.
Временное решение
В то же время вы можете использовать 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, потому что рассматриваются только открытые поля / получатели. С этим изменением этот 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
немного странно, но, к счастью, это волшебное заклинание, которое можно копировать / вставлять.
Это было окончательно исправлено в выпуске 9.6.
Исправлена ошибка, из-за которой передача производного класса в DatabaseReference#setValue() некорректно сохраняла свойства из суперкласса.
За:
Не найден сеттер / поле для motherAttribute в классе uk.edume.edumeapp.TestChild
установить сеттер для класса TestChild:
public class TestMother {
private String motherAttribute;
public String getMotherAttribute() {
return motherAttribute;
}
//set
public void setMotherAttribute(String motherAttribute) {
this.motherAttribute= motherAttribute;
}
}
Проверьте это https://firebase.google.com/support/guides/firebase-android
это говорит
"Если в вашем JSON есть дополнительное свойство, которого нет в вашем классе Java, вы увидите это предупреждение в файлах журнала: W/ClassMapper: не найден параметр / поле для ignoreThisProperty для класса com.firebase.migrationguide.ChatMessage"
Blockquote
Вы можете избавиться от этого предупреждения, поместив аннотацию @IgnoreExtraProperties в свой класс. Если вы хотите, чтобы база данных Firebase вела себя так же, как в 2.x SDK, и выдает исключение, если есть неизвестные свойства, вы можете добавить аннотацию @ThrowOnExtraProperties для вашего класса.
Blockquote