Can't Marshall Firebase Value Properly

I have an app that writes to the DB on the firebase realtime database. I can see the data and its fine.

I then simply want to read the data, and automatically marshall it into my object. There are a few layers to the JSON:

  "subjects" : {
    "reports" : {
      "A3VDf5q3gXefuFdK98OikTQYKEu2" : { <--multiple ones of these
        "report" : {
          "email" : "[email protected]",
          "profile_image" : "<LINK REMOVED>",
          "question_one" : {
            "answer" : "NO",
            "question" : "Blah blah?",
            "reason" : "meh"
          "question_two" : {
            "answer" : "NO",
            "question" : "Meh Meh?",
            "reason" : "bleh"
          "time_stamp" : "130719003955"

(I've removed some values for brevity and privacy)

In my code, I can manually extract the data:

final FirebaseAuth mAuth = FirebaseAuth.getInstance();
final FirebaseUser currentUser = mAuth.getCurrentUser();

final DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = database.child("subjects").child("reports").child(currentUser.getUid());
ref.addListenerForSingleValueEvent(new ValueEventListener() {
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        Log.d(TAG, "BEFORE CONVERSION::");
        Log.d(TAG, "User UID::" + currentUser.getUid());
        Log.d(TAG, "Children count::" + dataSnapshot.getChildrenCount());
        Log.d(TAG, "Snapshot key::" + dataSnapshot.getKey());
        Log.d(TAG, "Snapshot value::" + dataSnapshot.getValue());
        Log.d(TAG, "Snapshot toString::" + dataSnapshot.toString());

        Log.d(TAG, "email: " + dataSnapshot.child("report").child("email").getValue());
        Log.d(TAG, "profile image: " + dataSnapshot.child("report").child("profile_image").getValue());
        Log.d(TAG, "timeStamp: " + dataSnapshot.child("report").child("time_stamp").getValue());

        Report report = dataSnapshot.child("report").getValue(Report.class);
        Log.d(TAG, "Report: " + report.getProfileImage());
        Log.d(TAG, "Report to string: " + report.toString());

    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.e(TAG, "Failed to get value from DB", databaseError.toException());

Everything after Report report = dataSnapshot.child("report").getValue(Report.class); is null, EXCEPT email for some reason!! Obviously, I want to have it automatically set the values in my model:

public class Report {

    private String email;
    private String profileImage;
    private Question questionOne;
    private Question questionTwo;
    private String timeStamp;

    public Report() {}

    //Getters and setters

I've also tried putting the listener on: ref.child("report").addListenerForSingleValueEvent but it's the same result.

What am I doing wrong?




I believe you have to use the @PropertyName annotation on the public getter methods on Report, not the private field names.