java - Cómo deserializar una subclase en Firebase usando getValue(Subclass.class)
android jackson (4)
Estoy usando el nuevo Firebase SDK para Android y uso la función de base de datos real.
Cuando uso
getValue(simple.class)
todo está bien.
Pero cuando quiero analizar una clase que es una subclase, todos los atributos de la clase madre son
null
, y tengo este tipo de error:
No se encontró ningún setter / campo para el nombre en la clase 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;
}
}
esta función
snapshot.getValue(TestChild.class);
motherAttribute
atributo
motherAttribute
es
null
, y obtengo
No se encontró un setter / field para motherAttribute en la clase uk.edume.edumeapp.TestChild
el Json que analizo es:
{
"childAttribute" : "attribute in child class",
"motherAttribute" : "attribute in mother class"
}
Aparentemente, esto finalmente se solucionó en la versión 9.6 .
Se solucionó un problema por el cual pasar una clase derivada a DatabaseReference # setValue () no guardaba correctamente las propiedades de la superclase.
Comprueba esto https://firebase.google.com/support/guides/firebase-android
dice
"Si hay una propiedad adicional en su JSON que no está en su clase Java, verá esta advertencia en los archivos de registro: W / ClassMapper: No se ha encontrado ningún setter / campo para ignoreThisProperty en la clase com.firebase.migrationguide.ChatMessage"
Blockquote
Puede deshacerse de esta advertencia poniendo una anotación @IgnoreExtraProperties en su clase. Si desea que Firebase Database se comporte como lo hizo en el 2.x SDK y arroje una excepción si hay propiedades desconocidas, puede poner una anotación @ThrowOnExtraProperties en su clase.
Blockquote
para:
No se encontró un setter / field para motherAttribute en la clase uk.edume.edumeapp.TestChild
poner setter para la clase TestChild:
public class TestMother {
private String motherAttribute;
public String getMotherAttribute() {
return motherAttribute;
}
//set
public void setMotherAttribute(String motherAttribute) {
this.motherAttribute= motherAttribute;
}
}
Firebaser aquí
Este es un error conocido en algunas versiones de Firebase Database SDK para Android: nuestro serializador / deserializador solo considera propiedades / campos en la clase declarada.
Falta la serialización de las propiedades heredadas de la clase base en las versiones 9.0 a 9.6 (iirc) de Firebase Database SDK para Android. Fue agregado de nuevo en versiones desde entonces.
Solución alternativa
Mientras tanto, puede usar Jackson (que los SDK de Firebase 2.x usaron debajo del capó) para hacer que el modelo de herencia funcione.
Actualización
: aquí hay un fragmento de cómo puedes
leer
desde JSON en tu
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()
que hice público
getParentAttribute()
, porque solo se consideran los campos públicos / captadores.
Con ese cambio, este JSON:
{
"childAttribute" : "child",
"parentAttribute" : "parent"
}
Se vuelve legible con:
ObjectMapper mapper = new ObjectMapper();
GenericTypeIndicator<Map<String,Object>> indicator = new GenericTypeIndicator<Map<String, Object>>() {};
TestChild value = mapper.convertValue(dataSnapshot.getValue(indicator), TestChild.class);
El
GenericTypeIndicator
es un poco extraño, pero afortunadamente es un encantamiento mágico que se puede copiar / pegar.