Rasmus Rajje Josefsson Rasmus Rajje Josefsson - 6 months ago 181
JSON Question

Firebase onDataChange method on null object reference

This Is how I want it to look but I'm getting null object reference
inside of

(DataSnapshot wayPointsChild : wayPointsSnapshotChild.getChildren()) {


Those two property crashes everything

"timeStamp" : "2016/04/27 18:28:52",
"travelType" : "work"


JSON FROMAT

"waypoints" : {
"-KHB1VjqUdO90vxj9XCh" : {

"timeStamp" : "2016/04/27 18:28:52",
"travelType" : "work"

"-KHB1VjqUdO90vxj9XCi" : {
"latitude" : 58.337679,
"longitude" : 11.912757
},
"-KHB1ZykbwgXM9sPNie9" : {
"latitude" : 58.281384,
"longitude" : 12.294495
},

},
"-KHpPe06hLpPttuGZ0rZ" : {

"timeStamp" : "2016/04/27 18:28:52",
"travelType" : "private"

"-KHpPe07pE5ZYn4JGiZ1" : {
"latitude" : 58.281384,
"longitude" : 12.294495
},
"randomid1212" : {
"latitude" : 57.689903,
"longitude" : 11.989792
},
"randomid1213" : {
"latitude" : 57.689905,
"longitude" : 11.989795
},

}


The current onDataChange() method

mUserRef.addValueEventListener(new ValueEventListener() {
//this keeps per-user list of points
List<MyWaypoint> userWayPointsList = new ArrayList<MyWaypoint>();

@Override
public void onDataChange(DataSnapshot wayPointsDataSnapshot) {
if (wayPointsDataSnapshot.getChildrenCount() > 0) {


for (DataSnapshot wayPointsSnapshotChild : wayPointsDataSnapshot.getChildren()) {
Log.i("FireBaseTester", "For-Loop :: wayPointsSnapshotChild.getValue() : " + wayPointsSnapshotChild.getValue());
if (wayPointsSnapshotChild.getChildrenCount() > 0) {


// Temporary list
List<String> latLngListTemp = new ArrayList<>();


// THIS Gives me the error because it get used in the next for loop for some reason.
wayPointsSnapshotChild.child("timeStamp").getValue();


for (DataSnapshot wayPointsChild : wayPointsSnapshotChild.getChildren()) {

//this is where we get the Lat and Lon
double latitude = Double.parseDouble(wayPointsChild.child("latitude").getValue().toString());
double longitude = Double.parseDouble(wayPointsChild.child("longitude").getValue().toString());
Log.i("FireBaseTester", "latitude = " + latitude + " , longitude = " + longitude);

latLngListTemp.add(latitude + ", " + longitude);

}

// List containing a nested List<List<String>>
latitudeNlongitude.add(latLngListTemp);
}

}

}

//here you can assign the points to the user
Log.i("FireBaseTester", "There are " + userWayPointsList.size() + " Points for User");
}

@Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("FireBaseTester", "onCancelled - wayPointRef Error is " + firebaseError.getMessage());
}
});
} else {
Log.i("FireBaseTester", "No WayPoints Data Received");
}


LOGCAT


FATAL EXCEPTION: main
Process: com.example.rasmusjosefsson.rjcar, PID: 25446
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String java.lang.Object.toString()' on a null object
reference
at
com.example.rasmusjosefsson.rjcar.demo.MapListActivityRealBack2$1.onDataChange(MapListActivityRealBack2.java:122)
at
com.firebase.client.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:56)
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:5417)
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)

Answer

These lines demonstrate the problem:

wayPointsSnapshotChild.child("timeStamp").getValue();
for (DataSnapshot wayPointsChild : wayPointsSnapshotChild.getChildren()) {
{ 
  double latitude = Double.parseDouble(wayPointsChild.child("latitude").getValue().toString());

Calling getChildren on wayPointSnapshotChild will return the timestamp value as one of the children, which doesn't have a child called latitude.

You could structure your data like this:

"waypoints" : {
    "-KHB1VjqUdO90vxj9XCh" : {

      "timeStamp" : "2016/04/27 18:28:52",
      "travelType" : "work"
      "points": {
          "-KHB1VjqUdO90vxj9XCi" : {
            "latitude" : 58.337679,
            "longitude" : 11.912757
          },
          "-KHB1ZykbwgXM9sPNie9" : {
            "latitude" : 58.281384,
            "longitude" : 12.294495
          }
      }
    }

Then in your for loop call it:

wayPointsSnapshotChild.child("points").getChildren()

Then the inner loop would only receive wayPointChild objects which contain latitude and longitude properties.