Imad Imad - 6 months ago 129
Android Question

Android/Firebase: Why does onDataChange() returns null values?

My application allows a user to add details about a place when a marker is added on the Google map. These details are stored within Firebase with all details which are NOT null.

Here is the UPDATED tree:

{
"Algiers" : {
"Description" : "Capital of Algeria",
"Latitude" : 36.77202162442747,
"Longitude" : 3.0560945346951485,
"Rating" : "9",
"Type" : "Town"
},
"Brussels" : {
"Description" : "Capital of Belgium",
"Latitude" : 50.850103621427685,
"Longitude" : 4.3520765751600266,
"Rating" : "8",
"Type" : "Town"
},
"Burger King" : {
"Description" : "Fast but not healthy food",
"Latitude" : 51.236331,
"Longitude" : -0.575385,
"Rating" : 5.29,
"Type" : "Restaurant"
},
"Chippy Pizza" : {
"Description" : "Best American pizza ever",
"Latitude" : 36.72722332469427,
"Longitude" : 3.0647138133645058,
"Rating" : "10",
"Type" : "Restaurant"
},
"European Parliament" : {
"Description" : "Some decisions about Europe are done there",
"Latitude" : 50.83868986886192,
"Longitude" : 4.375510700047016,
"Rating" : "8",
"Type" : "Museum"
},
"Friary Center McDonalds" : {
"Description" : "Good food",
"Latitude" : 51.23544690507358,
"Longitude" : -0.5764660611748695,
"Rating" : "7.4",
"Type" : "Restaurant"
},
"Guildford Town Center" : {
"Description" : "Town center of Guildford",
"Latitude" : 51.23622,
"Longitude" : -0.570409,
"Rating" : 8.74,
"Type" : "Town"
},
"Guildfords Castle" : {
"Description" : "Very old castle",
"Latitude" : 51.23428622281793,
"Longitude" : -0.5723629519343376,
"Rating" : "8",
"Type" : "Museum"
},
"Guildfords Hospital" : {
"Description" : "Treats all types of pathologies",
"Latitude" : 51.240506,
"Longitude" : -0.60838,
"Rating" : "9",
"Type" : "Hospital"
},
"Guildfords Museum" : {
"Description" : "Museum with several exhibitions",
"Latitude" : 51.233797,
"Longitude" : -0.573549,
"Rating" : "7.84",
"Type" : "Museum"
},
"Martyrs Monument" : {
"Description" : "Describes the History of Algeria",
"Latitude" : 36.745560268045196,
"Longitude" : 3.0698012933135033,
"Rating" : "10",
"Type" : "Museum"
},
"Military Hospital" : {
"Description" : "Excellent Hospital",
"Latitude" : 36.71973881144668,
"Longitude" : 3.063882999122143,
"Rating" : "10",
"Type" : "Hospital"
},
"Mount Alvernia Hospital" : {
"Description" : "Small and correct hospital",
"Latitude" : 51.23583085374619,
"Longitude" : -0.5647089332342148,
"Rating" : "7",
"Type" : "Hospital"
},
"Mustapha Bacha Hospital" : {
"Description" : "Complete Hospital",
"Latitude" : 36.76243892522928,
"Longitude" : 3.053263798356056,
"Rating" : "7",
"Type" : "Hospital"
},
"Nandos Guildford" : {
"Description" : "Tasty but expensive chicken",
"Latitude" : 51.236343270137674,
"Longitude" : -0.5743494629859924,
"Rating" : "9",
"Type" : "Restaurant"
},
"Pach├ęco Hospital" : {
"Description" : "Excellent Hospital",
"Latitude" : 50.854205318946484,
"Longitude" : 4.349818155169487,
"Rating" : "10",
"Type" : "Hospital"
},
"Paris" : {
"Description" : "Capital",
"Latitude" : "48.84191426189115",
"Longitude" : "2.3034103587269783",
"Rating" : "8",
"Type" : "Town"
},
"Starbucks Coffee" : {
"Description" : "All types of coffee are found there",
"Latitude" : 51.235304,
"Longitude" : -0.575049,
"Rating" : 7.84,
"Type" : "Restaurant"
},
"Test 2" : {
"Description" : "Test",
"Latitude" : "26.567103702363973",
"Longitude" : "2.967230938374996",
"Rating" : "8",
"Type" : "Town"
},
"Test Overflow" : {
"Description" : "Test",
"Latitude" : "31.29925316955398",
"Longitude" : "2.439718544483185",
"Rating" : "10",
"Type" : "Town"
},
"Test3" : {
"Description" : "Testf",
"Latitude" : "45.24608905762172",
"Longitude" : "3.4947332739830017",
"Rating" : "8",
"Type" : "Town"
}
}


I am using the Firebase docs to retrieve data from my database (using
onDataChange()
).

However, my application crashes and prints me the following error:

05-16 14:37:15.772 13332-13332/org.com1032.flagged_v2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.com1032.flagged_v2, PID: 13332
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
at org.com1032.flagged_v2.MainActivity$6.onDataChange(MainActivity.java:877)
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:135)
at android.app.ActivityThread.main(ActivityThread.java:5219)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)


After some Logs, I realized that all values of that specific key are null.

Here is the code for retrieving the data from Firebase:

firebaseMarkers.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {

String descPath = dataSnapshot1.getKey() + "/Description";
String latPath = dataSnapshot1.getKey() + "/Latitude";
String lonPath = dataSnapshot1.getKey() + "/Longitude";
String ratePath = dataSnapshot1.getKey() + "/Rating";
String typePath = dataSnapshot1.getKey() + "/Type";


Log.v("INSERTING?", "MAYBE");
Log.v("the KEY", dataSnapshot1.getKey());
Log.v("TYPE:", dataSnapshot.child(typePath) + "");
Log.v("NAME:", dataSnapshot1.getKey());
Log.v("LATITUDE:", dataSnapshot.child(latPath).getValue().toString());
Log.v("LONGITUDE:", dataSnapshot.child(lonPath).getValue().toString());
Log.v("RATING:", dataSnapshot.child(ratePath).getValue().toString());
Log.v("DESCRIPTION", dataSnapshot.child(descPath).getValue().toString());

markersDatabase.insertData(dataSnapshot.child(typePath).getValue().toString(), dataSnapshot1.getKey(),
Double.parseDouble(dataSnapshot.child(latPath).getValue().toString()), Double.parseDouble(dataSnapshot.child(lonPath).getValue().toString()),
dataSnapshot.child(ratePath).getValue().toString(), dataSnapshot.child(descPath).getValue().toString());




Log.v("INSERTED!", "YES");

}
}


@Override
public void onCancelled(FirebaseError firebaseError) {
Log.v("Firebase Error", "Wow, you're asking very deep");
}
});


Each time I add a data, everything is stored onto a local database in the phone (all duplicates are removed after).

Here is the code for adding data into the firebase:

fire.child(markerName.toString()).setValue(markerName.toString());
fire.child(markerName.toString()).child("Description").setValue(markerDescription.toString());
fire.child(markerName.toString()).child("Latitude").setValue(String.valueOf(point.latitude));
fire.child(markerName.toString()).child("Longitude").setValue(String.valueOf(point.longitude));
fire.child(markerName.toString()).child("Rating").setValue(markerRating.toString());
fire.child(markerName.toString()).child("Type").setValue(markerType.toString());

MarkerOptions marker = new MarkerOptions().position(new LatLng(point.latitude, point.longitude)).title(markerName);
map.addMarker(marker);

markersDatabase.insertData(markerType, markerName, point.latitude, point.longitude, markerRating, markerDescription);


Thank you in advance.

Answer

So basically, I found the answer by myself.

The problem was in inserting data into Firebase. I was using the setValue() method which was not really the best way with the values I was using.

The best way is to create a new HashMap where you will be going to put your path and the value, as the example below:

Map<String, String> map2 = new HashMap<String, String>();
map2.put("Description", markerDescription);
map2.put("Latitude", String.valueOf(point.latitude));
map2.put("Longitude", String.valueOf(point.longitude));
map2.put("Rating", markerRating);
map2.put("Type", markerType);
Firebase fire = new Firebase("********").child(markerName);
fire.setValue(map2);

This is basically the best way to insert data (at least in my case).

Comments