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

Firebaser here

This is a known bug in some versions of the Firebase Database SDK for Android: our serializer/deserializer only considers properties/fields on the declared class.

Serialization of inherited properties from the base class, is missing in the in releases 9.0 to 9.6 (iirc) of the Firebase Database SDK for Android. It was added back in versions since then.

Workaround

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 a magic incantation that can be copy/pasted.


This was apparently finally fixed in release 9.6.

Fixed an issue where passing a derived class to DatabaseReference#setValue() did not correctly save the properties from the superclass.