java android jackson firebase-realtime-database json-deserialization

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.