Imad
Imad

Reputation: 84

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.

Upvotes: 1

Views: 7581

Answers (2)

qtmspin
qtmspin

Reputation: 119

The same thing was happening to me. The data looks identical in firebase. While debugging I could pull the data, however during runtime it would return null. For some reason, saving the hashmap to firebase works.

BTW if you use you can save yourself some casting.

    Map<String, Object> markerMap = new HashMap<String, Object>();

Upvotes: 0

Imad
Imad

Reputation: 84

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).

Upvotes: 1

Related Questions