I posted before but was not aware of the post standards for questions, so I have reformatted with code to back my issue.
I’m working on an app that uses Google Maps to take you on local tours and keep track of which Landmarks you have visited.
I have managed to write to the database (As shown in picture), but every time I try to read from the database, it claims that ulandmarks
is null and I’m trying to call .toString()
on a null object reference.
Here I have a Collection(“users”), a Document(uID), and a Field(“userLandmarks”) which contains an array of custom LandMark Objects.
I just want to take the list of userLandmarks for the current user and load them into a local list that I can use to populate a Google Map, but I can only retrieve a List of Map<String,Object>
.
Here is what I have tried and my Landmark class:
public void readUserData(String userID){ userID = getUserID(); CollectionReference usersRef = db.collection("users"); DocumentReference usersIdRef = usersRef.document(userID); usersIdRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() { @Override public void onComplete(@NonNull Task<DocumentSnapshot> task) { if (task.isSuccessful()) { DocumentSnapshot document = task.getResult(); if(document.exists()) { //This here returns a map but I want a list of Landmarks //List<Map<String, Object>> userLandmarks = (List<Map<String, Object>>) document.get("userLandmarks"); List<LandMark> ulandmarks = document.toObject(LandmarkDocument.class).landmarks; Log.v("DatabaseRead", "Successfully read from the database: "+ulandmarks.toString()); } } } }); } //Separate LandmarkDocument Class public class LandmarkDocument { public List<LandMark> landmarks; public LandmarkDocument(){} } public class LandMark { //GLOBALS private int mID; private String mName; private LatLng mLocation; private double mLatitude; private double mLongitude; private String mDesc; private int mImage; private boolean isVisited; //GLOBALS public LandMark() { } public LandMark(int mID, String mName, double mLatitude, double mLongitude, String mDesc, int mImage, boolean isVisited) { // ID and NAME this.mID = mID; this.mName = mName; // LOCATION, LATITUDE, and LONGITUDE this.mLocation = new LatLng(mLatitude, mLongitude); this.mLatitude = mLatitude; this.mLongitude = mLongitude; // LANDMARK DESCRIPTION this.mDesc = mDesc; // LANDMARK IMAGE this.mImage = mImage; // BOOLEAN VISITED FLAG this.isVisited = isVisited; } public String getName() { return mName; } public void setName(String mName) { this.mName = mName; } public LatLng getLocation() { return mLocation; } public double getLatitude(){ return mLatitude; } public void setLatitude(double mLatitude){ this.mLatitude = mLatitude; } public double getLongitude(){ return mLongitude; } public void setLongitude(double mLongitude){ this.mLongitude = mLongitude; } public void setLocation(double mLatitude, double mLongitude) { this.mLocation = new LatLng(mLatitude, mLongitude); } public String getDesc() { return mDesc; } public void setDesc(String mDesc) { this.mDesc = mDesc; } public int getID() { return mID; } public void setID(int mID) { this.mID = mID; } public int getImage(){ return mImage; } public void setImage(int mImage){ this.mImage = mImage; } public boolean isVisited(){ return isVisited; } public void setVisited(boolean isVisited){ this.isVisited = isVisited; } }
Please help.
Advertisement
Answer
You are getting the following error:
call .toString() on a null object reference
Because you are trying to get a landmarks
list that does not exist. The list in the database is called userLandmarks
and not landmarks
. To solve this issue, you should change the name of the field in the class to match the one in the database.
public class LandmarkDocument { public List<LandMark> userLandmarks; public LandmarkDocument(){} //... }
I also wrote an article that you might be interested in: