Search code examples
androidrealmrealm-list

Organize Android Realm data in lists


I'm looking into migrating our current app to realm and trying to figure out what's the best way to organize the data into ream. For this question I'll focus on the Photo object of my data model (but there're others).

All my data objects arrive from an API with endpoints such as: getPopular(), getNearbyPhotos(lat, lng), getUserPhotos(userId), getAlbumPhotos(albumId), getCollection(type). On most of those endpoints there're further parameters such as sort=best/chronological.

We're currently use this non-relational DB on the project which allows sorting and retrieving list of objects using only a listName. We use the listName as combination of the endpoit+parameters.

Realm (as a relational DB) uses standard queries, like:

realm.where(User.class)
     .contains("name", "Doe")
     .findAll();

that works fine when all the data is available locally, but the problem here is that a lot of the data for those queries are kept on the server side and never sent to the client. For example the Photo model does not contain location nor a score for best sorting.

On my current test project, I'm working around that by creating a ListPhoto similar to what our current project uses object as:

public class ListPhoto extends RealmObject {
   @PrimaryKey public String id;
   public RealmList<Photo> list;
}

and using the actual API endpoint and parameters as id.So I'm able to find those objects with a simple query

ListPhoto listPhoto = realm
          .where(ListPhoto.class)
          .equalTo("id", id)
          .findFirst();

But with that approach I'm creating an extra layer of abstraction to simply store grouping and ordering metadata, which I'm not happy with and I ask here:

how could I query data on realm based simply on the order and group that it was inserted without using this dirty hack I came up with?

edit:

follow-up question to that: Query realm data contained on other object


Solution

  • But because it's data that is never visually presented to the user, it is not sent to the client (I would like to migrate to Realm, but would be better to do it without having to change server-side data models and endpoit behaviors)

    That's pitiful but understandable.

    What you can do is give your realm Photo objects the fields anyway, like

    public class Photo extends RealmObject {
        // other fields
    
        private double latitude;
        private double longitude;
        private String score;
    }
    

    Then, you query the server with the API endpoint and parameters as you do now.

    When the results are in, you store them in realm and also assign them the values for lat/long/score. You have these available at this point because you just used them in the server query.

    So if you query for api/getNearbyPhotos(1, 2)?sort=best:
    (pseudo code)

    api.fetch("getNearbyPhotos(1, 2)?sort=best", new GetPhotoCompleteListener {
        @Override
        void onSuccess(List<Photo> photos) {
            // assuming gson or something has already parsed the server response into photo objects
            for (Photo p : photos) {
                p.setLatitude(1);
                p.setLongitude(2);
                p.setScore("best");
            }
            realm.copyToRealmOrUpdate(photos);
        }
    }
    

    Now you have a bunch of photo objects in realm that you can query in the same way as you did on the server.