How to retrieve a list of custom objects from Cloud Firestore in Android

Tags: , , , ,



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.

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.

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:



Source: stackoverflow