Super man Super man - 2 months ago 10
Android Question

UnrecognizedPropertyException when reading data from Firebase

I am trying to read the values stored in my Firebase Database. This is how the database looks like:

URL :

https://xxxx.firebaseio.com/Cohesion/Passes/Away/Arsenal


Firebase database

Now, from Android side, this is how I try to retrieve the data:

Firebase mRef = new Firebase("https://xxxx.firebaseio.com/Cohesion/Passes/Away/Arsenal");

mRef.addValueEventListener(new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Arsenal vals = dataSnapshot.getValue(Arsenal.class);
Log.e("retValue",""+vals);

}

@Override
public void onCancelled(FirebaseError firebaseError)
{
Log.e("REAL_ERROR",""+firebaseError);

}
});


Arsenal.class

public class Arsenal {

private int Cross;
private int LongBall;
private int ShortPass;
private int ThroughBall;

public Arsenal()
{

}

public Arsenal(int Cross,int LongBall,int ShortPass,int ThroughBall)
{
this.Cross = Cross;
this.LongBall = LongBall;
this.ShortPass = ShortPass;
this.ThroughBall = ThroughBall;
}
public int getCross() {
return Cross;
}


public int getLongBall() {
return LongBall;
}


public int getShortPass() {
return ShortPass;
}


public int getThroughBall() {
return ThroughBall;
}


}


I've set the
Rules
in console to
true
so it can be publicly accessed to read and write, and hence I am accessing without using authentication.

Here is the Logcat :


09-19 12:14:51.032 13585-13585/com.ihrd.myapplication
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ihrd.myapplication, PID: 13585
Theme: themes:{}
com.firebase.client.FirebaseException: Failed to bounce to type
at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:185)
at
com.ihrd.myapplication.MainActivity$1.onDataChange(MainActivity.java:28)
at
com.firebase.client.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:53)
at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45)
at
com.firebase.client.core.view.EventRaiser$1.run(EventRaiser.java:38)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "Cross" (class com.ihrd.myapplication.Arsenal), not
marked as ignorable (0 known properties: ])
at [Source: java.io.StringReader@e1c14e3; line: 1, column: 12]
(through reference chain: com.ihrd.myapplication.Arsenal["Cross"])
at
com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:555)
at
com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:708)
at
com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1160)
at
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:315)
at
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at
com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at
com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:183)
at
com.ihrd.myapplication.MainActivity$1.onDataChange(MainActivity.java:28) 
at
com.firebase.client.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:53) 
at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45) 
at
com.firebase.client.core.view.EventRaiser$1.run(EventRaiser.java:38) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5461) 
at java.lang.reflect.Method.invoke(Native Method) 
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)


What is possibly causing this? And how to fix? kindly help.

Answer

When it finds a class with getters and setters, Firebase uses a JavaBean naming convention to determine the underlying JSON property names.

This means that

public class Arsenal {
    private int Cross;

    public int getCross() {
        return Cross;
    }
}

Translates to this JSON:

cross: 19

You'll see that the case is different. As far as I can see, you have a few options:

1 - change the case of the JSON property

If you start the property names in JOSN with a lowercase character, things will work with you current code:

cross: 19

2 - use public fields instead of getters/setters

If you only have public fields, Firebase will use the exact name of those fields for the JSON mapping:

public class Arsenal {
    public int Cross;
}

3 - annotate the class to get the correct mapping

The final solution is to put an annotation on the class to help Firebase find the corresponding JSON property.

Since you're using the Firebase 2.x SDK, the annotation is JsonProperty from Jackson:

public class Arsenal {
    private int Cross;

    @JsonProperty("Cross")
    public int getCross() {
        return Cross;
    }
}

In Firebase 3.x, the corresponding annotation is PropertyName:

public class Arsenal {
    private int Cross;

    @PropertyName("Cross")
    public int getCross() {
        return Cross;
    }
}