43

I am using Realm as a back end in my application. I have created one table named Setting. I added values in that table, by following the steps given on Realm's official site. But when I am going to retrieve values from that table in, I getting exception

"io.realm.exceptions.RealmMigrationNeededException: RealmMigration must be provided" on the line:" realm=Realm.getInstance(getApplicationContext());".

Actually, I am new to android and Realm, so finding trouble to understand what is problem.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Sanket Ranaware
  • 603
  • 2
  • 6
  • 13

5 Answers5

80

EDIT: for new versions of Realm, Realm.init(Context context) is added

Realm.init(context);    
RealmConfiguration config = new RealmConfiguration
                                     .Builder()
                                     .deleteRealmIfMigrationNeeded()
                                     .build();

NOTE: With this config option, any schema change will result in loss of data, specifically:

  • a field is added/removed
  • a new RealmObject class is added
  • an existing RealmObject is removed
  • @Required is added/removed
  • @PrimaryKey is added/removed
  • @Index is added/removed

So it's primarily recommended while the app is in the development stage.


Or add a migration following the official docs:

https://realm.io/docs/java/latest/#migrations

For example,

public class Migration implements RealmMigration {
    @Override
    public void migrate(final DynamicRealm realm, long oldVersion, long newVersion) {
        RealmSchema schema = realm.getSchema();

        if (oldVersion == 0) {
            RealmObjectSchema personSchema = schema.get("Person");
            personSchema
                .addField("fullName", String.class, FieldAttribute.REQUIRED);
            oldVersion++;
            ... 

  // hash code, equals 

And

Realm.init(context);    
RealmConfiguration config = new RealmConfiguration.Builder() 
                                 .migration(new Migration()) 
                           //      .deleteRealmIfMigrationNeeded()
                                 .build();
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
1911z
  • 1,073
  • 10
  • 15
  • `RealmConfiguration config = new RealmConfiguration.Builder(context).deleteRealmIfMigrationNeeded().build()` on my realm version 2.0.0. `Builder(Context context)` is not public – Merhawi Fissehaye Oct 26 '16 at 13:56
  • 4
    If you are wondering how to use "config", try this: realm.getInstance(config); – Kai Wang Feb 14 '17 at 16:55
  • 1
    or just `Realm.setDefaultConfiguration(config)` and so on. – EpicPandaForce Sep 05 '17 at 19:22
  • If it still does not work, try reinstalling your app. Worked for me – Daniyal Javaid Jan 21 '19 at 18:01
  • @EpicPandaForce if we have two DBs to access in the same app, then how can one setDefaultConfig, wouldn't the realm always only use the defaultconfig file?. Please explain. I am having diffculty in understanding the concept, if I have more than one DBs to use. – Rishabh Sahrawat Nov 18 '19 at 14:34
  • @RishabhSahrawat if you have two configurations, then you should use the `name("otherRealm.realm")` argument of `RealmConfiguration.Builder`. You CAN have a `setDefaultConfig`, just be aware of what you are doing and when you are using the other configuration with `Realm.getInstance(otherRealmConfig)`. – EpicPandaForce Nov 18 '19 at 16:11
  • I got it now. So, now I have two DBs in different schemas (files), when I wanna access them I am facing MIGRATION errors. After googling, I understood that I have to add one of the schemas (one file data) to other and then I can access the file having both DBs. But I am not sure exactly how to do that. Maybe you have any links etc.. I am following [this](https://realm.io/docs/java/latest/#migrations) for now. – Rishabh Sahrawat Nov 18 '19 at 16:16
  • @EpicPandaForce , Please check https://stackoverflow.com/questions/59855380/how-can-i-replace-a-listobjects-with-object-field-in-realm about realm migration – milad salimi Jan 25 '20 at 07:39
20

if you upload the app to store, the "delete and reinstall the app" will not working to other user, so you must working with "deleting" the realm and "reinstalling" the realm, not the app. here's the way to do it, hope it'll helps!!

    RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(this).build();

    try {
        return Realm.getInstance(realmConfiguration);
    } catch (RealmMigrationNeededException e){
        try {
            Realm.deleteRealm(realmConfiguration);
            //Realm file has been deleted.
            return Realm.getInstance(realmConfiguration);
        } catch (Exception ex){
            throw ex;
            //No Realm file to remove.
        }
    }

EDIT

For the newest Realm (3.0.0), Realm has changes the constructor structure, so you must do something like this :

Realm.init(context);    
RealmConfiguration config = new RealmConfiguration
                                 .Builder()
                                 .deleteRealmIfMigrationNeeded()
                                 .build();
yfsx
  • 1,906
  • 14
  • 17
15

You changed something to the realm structure.

In order to fix it you should include the migration or simply remove the application and install it again.

Lars Celie
  • 622
  • 5
  • 17
  • Yupp, it worked, I re-installed app... Thanks a lot buddy – Sanket Ranaware Nov 26 '15 at 13:47
  • In case you're new, you can mark this answer as 'working' by 'accepting' it. (On the left a 'v' mark) – Lars Celie Nov 26 '15 at 13:49
  • One more thing I want to ask is, as I have now retrieved values in "RealmResults". I have attributes in my table as "id,name, values". How can I get value of "values " column seperately.."??? – Sanket Ranaware Nov 26 '15 at 14:04
  • you can only get the whole objects, so you can do a FindAll() and loop through the .getValues() part – Lars Celie Nov 26 '15 at 14:06
  • Actually it is not showing option of getValues(), but I did get(i); but it is providing entire row and I want single value from that row. My code is "settingDataList.get(0);" – Sanket Ranaware Nov 26 '15 at 14:11
  • You could do it in a different way, Data data = realm.where(data.class).equalTo("values","my wanted value").findFirst() which will return a single object of Data, and then you can do something with data. – Lars Celie Nov 26 '15 at 14:28
  • Basically, the only way to get a single value is to get the whole row as object first, and then use the getter to retrieve the wanted value. – Lars Celie Nov 26 '15 at 14:30
  • For example, I changed the version of Realm and got this error. Just reinstall it. – Mladen Rakonjac Jun 25 '16 at 20:31
5

That works for me

    Realm.init(context);
    Realm realm;
    try{
        realm = Realm.getDefaultInstance();

    }catch (Exception e){

        // Get a Realm instance for this thread
        RealmConfiguration config = new RealmConfiguration.Builder()
                .deleteRealmIfMigrationNeeded()
                .build();
        realm = Realm.getInstance(config);

    }
Cedriga
  • 3,860
  • 2
  • 28
  • 21
-1

Kotlin version:

val realm = try {
            Realm.init(this)
            val config = RealmConfiguration.Builder()
                    .deleteRealmIfMigrationNeeded()
                    .build()
            Realm.getInstance(config)
        } catch (ex: RealmMigrationNeededException) {
            Realm.getDefaultInstance()
        }
Andrii Kovalchuk
  • 4,351
  • 2
  • 36
  • 31