15

I have this class making use of enums. Parsing to Firebase json used to work just fine - using Jackson. While migrating to firebase-database:9.0.0 I get the following:

com.google.firebase.database.DatabaseException: No properties to serialize found on class .... MyClass$Kind

where Kind is the enum declared type. The class:

public class MyClass {

    public enum Kind {W,V,U};

    private Double value;
    private Kind kind;

    /* Dummy Constructor */
    public MyClass() {}

    public Double getValue() {
        return value;
    }

    public void setValue(Double value) {
        this.value = value;
    }

    public Kind getKind() {
        return kind;
    }

    public void setKind(Kind kind) {
        this.kind = kind;
    }
}

I suspect Firebase no longer uses Jackson when serializing setValue(new MyClass()).

Is there a way to get enum types serialized? Or some means to be explicit with respect to the serializer method?

rmarau
  • 388
  • 1
  • 4
  • 12
  • 1
    I'd reconsider accepting an answer that is clearly not a long-term solution. While it's nice to not have to import Jackson anymore, we have given up control of our code for shiny new features that many of us don't need. Until Firebase allows us to configure the JSON serializer through their SDK, I'd argue that there is no acceptable solution at the moment. – Anthony Chuinard Jul 26 '16 at 15:59

2 Answers2

18

You are right, Firebase Database no longer uses Jackson for serialization or deserialization.

You can represent your enum as a String when talking to Firebase by doing this:

public class MyClass {

    public enum Kind {W,V,U};

    private Double value;
    private Kind kind;

    /* Dummy Constructor */
    public MyClass() {}

    public Double getValue() {
        return value;
    }

    public void setValue(Double value) {
        this.value = value;
    }

    // The Firebase data mapper will ignore this
    @Exclude
    public Kind getKindVal() {
      return kind;
    }

    public String getKind() {
        // Convert enum to string
        if (kind == null) {
          return null;
        } else {
          return kind.name();
        }
    }

    public void setKind(String kindString) {
        // Get enum from string
        if (kindString == null) {
          this.kind = null;
        } else {
          this.kind = Kind.valueOf(kindString);
        }
    }
}
Sam Stern
  • 24,624
  • 13
  • 93
  • 124
  • 1
    Thanks, that helps! I've just added the null checks. And for the sake of completeness in Kind.valueOf one should also verify the IllegalArgumentException. But the intentions of what to do may vary here. – rmarau May 21 '16 at 16:36
  • Added the null checks, thanks! Could you mark the answer as accepted if this worked for you? – Sam Stern May 21 '16 at 18:21
  • Thanks for the answer, does anybody know why the Jackson serialisation has been removed? it was pretty handy... – Marco Hernaiz Jul 01 '16 at 16:26
  • @MarcoHC part of the concern was the size of the dependency when the Database was only using a small subset of Jackson. Is there something missing from the new implementation for you? – Sam Stern Jul 01 '16 at 17:36
  • @hatboysam ok I understand. No, just the enum thing, the rest is ok. Thanks – Marco Hernaiz Jul 04 '16 at 16:04
  • 2
    @hatboysam The original problem still exists, Firebase not turning enums into Strings (as the previous behavior did) is missing. Can't this be fixed? It's kind of ironic how one of the top software companies in the world is recommending a hacky solution like this. Not everyone gets to modify their POJOs, too. – Anthony Chuinard Jul 26 '16 at 15:12
6

Just as a side optimizing answer In Android, it is recommended not to use Enums. Use @StringDef or @IntDef, that it could be working without workarounds and you optimized your app for memory.

Very nice video reasoning why: https://www.youtube.com/watch?v=Hzs6OBcvNQE

aselims
  • 1,843
  • 1
  • 17
  • 19