Search code examples
androidrealmrealm-list

fetch realm data based on dynamic type


I have created following classes in realm for entities like employee , Student and storing its sync status in SyscInfo class

Employee extends RealmObject      
  _id
  name
  phone
  address
  isSync

Student extends RealmObject      
 _id
 name
 phone
 isSync


SyncInfo extends RealmObject      
  isSync
  timestamp

Now if any emploee or student records are not synced i am setting syncInfo.isSync to false

my background scheduler will check whether we have any offline / not synced data stored in realm db. for that i am firing query for employee and student both.

    RealmList<Employee> offlineEmployeeList = realm.where(Employee.class).equalTo("syncInfo.isSync",false).findAllAsync();
    RealmList<Student> offlineEmployeeList = realm.where(Student.class).equalTo("syncInfo.isSync",false).findAllAsync();

so what i am looking is , do we have any generalized way to check offline / unsynced data without checking into each entity i.e. Employee and Student. tomorrow if one more entity got introduced , i again have to fire the same query.


Solution

  • You can create this generic method:

    private <T extends RealmModel> RealmResults<T> getNotSynced(Class<T> modelClass) {
        return realm.where(modelClass).equalTo("isSynced", false).findAll();
    }    
    

    And use it like this:

    Set<Class<? extends RealmModel>> realmObjectClasses = realm.getConfiguration().getRealmObjectClasses();
    
    ArrayList<RealmResults> notSynched = new ArrayList<>();
    for(Class modelClass: realmObjectClasses) {
      notSynched.add(getNotSynced(schemaClasses));
    }
    
    // Now you have an array of RealmResults with non-synched RealmObjects
    

    About the query method,

    I would use the findAll() method and execute the hole thing on a background thread, and not the findAllAsync(), the later requires a more complex synchronisation as I see it.

    UPDATE

    If not all RealmObjects has the isSynced field, here is what I would do:

    RealmObjects has some limitations, but you can implement an empty interface, so I would use that to identify syncable objects and use the getNotSynced method only on them:

    Create an empty interface:

    public interface Syncable {}
    

    Implement it with all the syncable RealmObjects:

    Employee extends RealmObject implements Syncable {
      ...
    }
    

    And then use it to filter the classes in the for loop from before:

    for(Class modelClass: realmObjectClasses) {
      if (Syncable.class.isAssignableFrom(modelClass)) {
        notSynched.add(getNotSynced(schemaClasses));
      }
    }