How to deal with destructive changes in synced realm

cloud
ros
platform

#1

Hi,

I have a synced realm in production (Realm Cloud), and i need set an old field as @PrimaryKey.
I know that is a destructive change, and Realm cannot deal with that alone, but how can i do this manually without losing my data? I mean, i can’t simply delete my old realm and start a new one, i need to migrate my old Realm to my new one. Unfortunately the doc for this use case are too superficial!

I tried to use DynamicRealm to get my old realm and insert all objects into new realm, like this:

private void copyLocalRealmToSyncedRealm(@NonNull final MigrationListener migrationListener) {
        RealmConfiguration oldConfig = orderQuery.getSyncConfig();
        RealmConfiguration newConfig = orderQuery.getNewSyncConfig();
        if (oldConfig != null && newConfig != null) {
            final Realm newRealm = Realm.getInstance(newConfig);
            final DynamicRealm oldRealm = DynamicRealm.getInstance(oldConfig);
            final Set<Class<? extends RealmModel>> classes = oldConfig.getRealmObjectClasses();
                newRealm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(@NonNull Realm realm) {
                        try {
                            if (!classes.isEmpty()) {
                                for (final Class type : classes) {
                                    String className = type.getSimpleName();
                                    final RealmResults<? extends RealmObject> realmModels = oldRealm.where(className).findAll();
                                    newRealm.insertOrUpdate(realmModels);
                                }
                            }
                            migrationListener.done();
                        } catch (Exception e) {
                            migrationListener.error();
                        }
                    }
                });
            }
    }

But, i got this exception:
io.realm.exceptions.RealmException: ‘class io.realm.RealmObject’ is not part of the schema for this Realm.


#2

Actually, i found the reason for this behavior:

The method findAll from DynamicRealm doesn’t return a specific object, the returned object is always a DynamicRealmObject. So, to do this migration we need to use some methods from DynamicRealmObject like getString( fieldname ) and create a mapper for every specific RealmObject that you have. Is quite annoying, and realm team should find a way easier to do this, but works!