drevlav drevlav - 5 months ago 110
Android Question

How to deserialise a subclass in Firebase using getValue(Subclass.class)

I m using the new firebase sdk for android and use the real database feature. when i use the getValue(simple.class) everything is fine. but when i want to parse a class which is a subclass, all the attribute of the mother class are null, and i have this type of error :
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;
}
}


this function

snapshot.getValue(TestChild.class);


"motherAttribute" attribute is null, and I get


No setter/field for motherAttribute found on class uk.edume.edumeapp.TestChild


the Json that i parse is:

{
"childAttribute" : "attribute in child class",
"motherAttribute" : "attribute in mother class"
}

Answer

Firebaser here

This is a known bug at the moment: our serializer/deserializer only considers properties/fields on the declared class.

Serialization of inherited properties from the base class, is missing in the current release of the Firebase Database SDK for Android. It will be added back in an upcoming version.

In the meantime you can use Jackson (which the Firebase 2.x SDKs used under the hood) to make the inheritance model work.

Update: here's a snippet of how you can read from JSON into your 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;
    }
}

You'll note that I made getParentAttribute() public, because only public fields/getters are considered. With that change, this JSON:

{
  "childAttribute" : "child",
  "parentAttribute" : "parent"
}

Becomes readable with:

ObjectMapper mapper = new ObjectMapper();
GenericTypeIndicator<Map<String,Object>> indicator = new GenericTypeIndicator<Map<String, Object>>() {};
TestChild value = mapper.convertValue(dataSnapshot.getValue(indicator), TestChild.class);

The GenericTypeIndicator is a bit weird, but luckily it's black magic that can be copy/pasted.

Comments