0

With an old Firebase (com.firebase:firebase-client-android:2.5.2) we can do this:

@JsonAutoDetect(
    fieldVisibility = JsonAutoDetect.Visibility.ANY,
    isGetterVisibility = JsonAutoDetect.Visibility.NONE,
    getterVisibility = JsonAutoDetect.Visibility.NONE,
    setterVisibility = JsonAutoDetect.Visibility.NONE)
public class BaseForEveryDataClass {
    //some library staff
}

This allows us to do these tricks:

public class Identity extends BaseForEveryDataClass {
    private String id;

    public String getId(){
        return id;
    };
    //(1) protect id from change, get it internally from firebase
}

public class Movie extends Identity {
    //(2) Firebase was detecting the id field for all ancestors of identity

    private String imdbId;
    public Movie(JSONObject json/*ApiResponse*/) {
        imdbId = json.getString("imdb"); //no setter, cannot change it outside
    }
    //(3) no getter for imdbId - it useless by itself, but have to be stored in a db

    //(4) I don't need field "imdbLink" stored in a db, it's calculated
    public String getImdbLink() {
        return Constants.IMDB_PREFIX+imdbId; 
    }
}

public class User extends Identity {
    //(2) no id field again in a Google-Firebase

    //(3) another completely hidden field
    private long remindToRateUs = 0;

    public boolean shouldShowRateDialog() {
        return remindToRateUs < System.currentTimeInMillis();
    }

    public void remindLater() {
        remindToRateUs = System.currentTimeInMillis() + Constants.MONTH;
    }
}

So these was working in Firebase 2.5 but I cannot find a way to do it easy and safe in Firebase 9 (Google-enhanced, com.google.firebase:firebase-database:9.0.2)

So, the questions:

(1+2) Is it a way, to persist all private fields in all base classes and the persisted class, like we've had in a old analog Firebase? I know we can workaround that with

//inside all ancestors
public int getId() {
    super.getId();
}

but it's very non error-proof and just unneeded extra work;

(3) How can we have hidden internal fields persisted after Google's upgrade? The workaround is to add externally visible getters and/or setters for them. But that makes your data class prone to outside hack, violates encapsulation.

(4) how can you disable persistence of ALL "utility-getters" (getters without backup of real data field, run-time calculated) at once without JsonAutoDetect? I know we can add @Exclude to each of them. Each of them, Carl!

@Google, why??? O_o It was working fine!

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Yan.Yurkin
  • 970
  • 8
  • 15

1 Answers1

1

firebaser here

Versions 1.x and 2.x of the Firebase SDK for Android used Jackson internally for serializing/deserializing between JSON and Java objects. While Jackson is an incredibly powerful library, the dependency alone was responsible for over half of our jar size. For that reason we've replaced the Jackson dependency with custom serialization/deserialization in the latest release.

We've covered the main use-cases we knew of and are actively monitoring the community for use-cases we might have missed. When such a case is identified, we consider if we can add it without impacting APKs that don't need the functionality too much.

Even while the functionality you need is missing from the Firebase SDK, you can easily revert to the previous behavior by explicitly depending on Jackson and using that again. See my answer to this question for an example of that: How to deserialise a subclass in Firebase using getValue(Subclass.class)

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks for the options. I'm fine with depending from Jackson. But I really cannot imagine some base method in a root base class to make it once and not copy-paste it in every place where I need data. – Yan.Yurkin Jun 23 '16 at 15:10
  • Sorry, I cannot accept it as an answer, 'cause it's not answering any of my questions. – Yan.Yurkin Jun 25 '16 at 09:26