0

I am drawing a route between two markers, and I want to save that route. To do that I saved the ArrayList containing the lat and lng in the Firebase database. But I am having problems retrieving the waypoints. This is how I inserted:

String routeId = database.push().getKey();
database.child(sharedPreferences.getString("school", null)).child("routes").child(routeId).setValue(points);
SharedPreferences.Editor editor = getActivity().getSharedPreferences("sh", MODE_PRIVATE).edit();
            editor.putString("key", routeId);
            editor.commit();

Where the sharedPreferences string "school" is the name of the school, routeId is a push() key and the points is an ArrayList of waypoints.

My database:

database structure

My POJO classes:

public static class Route {

    private ArrayList<Location> locations;

    public Route() {
    }

    public ArrayList<Location> getLocations() {
        return locations;
    }

    public void setLocations(ArrayList<Location> locations) {
        this.locations = locations;
    }
}


public static class Location {
    private Double latitude;
    private Double longitude;

    public Location() {
    }

    public Double getLatitude() {
        return latitude;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public Double getLongitude() {
        return longitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }
}

Retrieval of waypoints:

  points = new ArrayList();
    userRef.child(sharedPreferences.getString("school", null)).child("routes").child(sh.getString("key",null)).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Route route = dataSnapshot.getValue(Route.class);
            for (Location location : route.getLocations()) {
                double lat = location.getLatitude();
                double lng = location.getLongitude();
                position = new LatLng(lat, lng);
                points.add(position);
            }
        }

But I am getting a database exception:

DatabaseException: Can't convert object of type java.util.ArrayList to type packagename

I don't know why.

Grimthorr
  • 6,856
  • 5
  • 41
  • 53
JDoe
  • 221
  • 4
  • 14

2 Answers2

1

Your code is almost right, but I think it's the saving of the data that's letting it down. When you load the data back from the database you're marshalling the data into a Route instance:

Route route = dataSnapshot.getValue(Route.class);

This will expect a locations node under each child to match setLocations(ArrayList<Location>) in your POJO class. Instead, the data it retrieves is the ArrayList directly.

When saving your location list, you'll need to arrange the structure such that the list of locations are stored under $schoolName/routes/$routeId/locations:

database structure

So, when saving your route point data, you'll need to do:

database.child(schoolName).child("routes").child(routeId).child("locations").setValue(points);

An easy way to think of this would be: if the Route also had a name field (setName(String)) then the database may also have $schoolName/routes/$routeId/name in the same place as the locations value.

Alternatively, when saving to the database, you could convert your points variable to a Route instance and then push that directly to $schoolName/routes/$routeId instead, which will ensure that it's stored correctly.

Grimthorr
  • 6,856
  • 5
  • 41
  • 53
  • Thanks for the answer. If I go by your second solution: The `points` variable is an arraylist. Is there a simple way to convert it to a `Route` instance? – JDoe Oct 25 '17 at 13:34
  • Is the `points` variable already an `ArrayList`? You could just do `Route route = new Route(); route.setLocations(points);` or create a constructor for it. – Grimthorr Oct 25 '17 at 13:37
  • Quick question: The code that is running inside `onDataChange`, will that only take the last added waypoints? – JDoe Oct 25 '17 at 14:29
  • It will iterate through each child that has been pushed to the `routes` node. If you only want the latest, you'll need to use a query to [sort and filter](https://firebase.google.com/docs/database/android/lists-of-data#sorting_and_filtering_data) them: you can append `orderByKey()` and `limitToLast(1)` to your reference to only obtain the most recent. – Grimthorr Oct 25 '17 at 14:43
  • Okay, I was thinking more of the opposite, so that I can draw as many polylines as childs in the 'routes' node. I will try to figure it out. Thanks :) – JDoe Oct 25 '17 at 14:56
0

Try this

    final HashMap<Integer,HashMap<String,Double>> positions = new HashMap<>();
    userRef.child(sharedPreferences.getString("school", null)).child("routes").child(sh.getString("key",null)).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            int i=0;
            for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
                HashMap<String,Double> position = new HashMap<String, Double>();
                position.put("lat",Double.parseDouble(postSnapshot.child("latitude").getValue().toString()));
                position.put("lng",Double.parseDouble(postSnapshot.child("longitude").getValue().toString()));
                positions.put(i++,position);
            }

        }

You can access the values stored in positions variable as

 positions.get(index).get("lat");
 positions.get(index).get("lng");
Sushin Pv
  • 1,826
  • 3
  • 22
  • 36
  • NumberFormatException: For input string: "DataSnapshot { key = lat, value = null – JDoe Oct 25 '17 at 08:42
  • I tried this also. I got the same error as before: DatabaseException: Can't convert object of type java.util.ArrayList to type packagename – JDoe Oct 25 '17 at 08:46
  • @JDoe Wait i know what the error is. I'll update the code – Sushin Pv Oct 25 '17 at 08:47
  • I get this error now: NumberFormatException: For input string: "DataSnapshot { key = latitude, value = 55.3975 } – JDoe Oct 25 '17 at 08:50