rosghub
rosghub

Reputation: 9264

Android Firebase Firestore unable to deserialize abstract class

I am migrating my existing app to use Firebase firestore. I am running into an issue with one of my models containing a list of objects inheriting an abstract class:

// Model
class Project {
    ...
    ArrayList<PaintItem> paintItems;
    ...
}

abstract class PaintItem {
    ...
}

class CeilingPaintItem extends PaintItem {
    ...
}

class WindowPaintItem extends PaintItem {
    ...
}

Storing a Project object works fine, but when retrieving it:

project = documents.toObject(Project.class)

It throws an exception trying to instantiate an abstract class (PaintItem). I suspect this is happening because under the hood, the serialization doesn't check what class each PaintItem actually is.

What is the best way to overcome this? By best I mean:

Upvotes: 1

Views: 929

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317692

Firstly, the most efficient solution is not to use automatic object mapping at all. It uses java reflection, which is not terribly fast. It's much faster at runtime to manage Maps and Lists on your own. There's not much you can do to improve the performance of reflection-based serialization, other than to use fewer fields.

Second, you can not have an interface or abstract class participate in object mapping serialization, as you've discovered. The Firebase SDK has no idea at all about any of the types of objects you used to serialize in the first place. It's simply looking at the getters and setters of each object (or public fields) to determine how to map object properties into fields, and the other way around. You must specify a concrete class with a no-arg constructor if you want to use automatic object mapping. If PaintItem is always going to be abstract, then at a minimum, you need a concrete subclass of PaintItem in Project for the SDK to be able to deserialize the object.

Upvotes: 3

Related Questions