Realm-java: Why does Realm.init set default configuration?

Created on 6 Jan 2019  路  10Comments  路  Source: realm/realm-java

Realm.init sets the default configuration. Why is this? In what case would the user of the library not set it's own configuration?

In my case it has led to a lot of confusion. Since I did not set my own default configuration straight away in my application subclass. For example when using Realm Cloud, you probably want to establish a sync configuration and never use a local configuration at all. And even if you use a local configuration, you probably don't want the default as you probably want custom migrations etc.

What I see happening now is that when the app is destroyed and recreated. Realm.init() is called again in application.oncreate. Then the app will crash with a very cryptic error message "provided schema version 0 is less than last set version". It took me a long time to understand that this was caused by Realm.init() setting an invalid default configuration.

I would much prefer if the app would crash with the error message "No default configuration set".

Breaking O-Community Pipeline-Idea-Backlog T-Enhancement

All 10 comments

You should always set the default configuration, possibly in Application.onCreate(), before you actually open the Realm with getDefaultInstance().

But you aren't the first one to say that setting a default in init() is a mistake: https://github.com/realm/realm-java/issues/4844#issuecomment-311713546

But what about the case when you are using realm cloud? I certainly cannot set the default configuration if the user is not logged in yet? Running Realm.init() will set a local default configuration, which will always be invalid, and I can't set the SyncConfiguration as default as the user is not signed in yet.

But I guess it means that I should always set the configuration whenever I can. When running a local configuration I should set the localConfiguration as default in Application.onCreate() and if I already have a current syncUser, I should be able to set the syncConfiguration in Application.onCreate()

But I agree with this being a mistake. The error messages this leads to are very confusing. Took me a long time to figure out that the issue was that Realm.init() sets a default configuration. I had no idea.

The one thing you can do on your side is wrap the init/getDefaultInstance() calls and detect if the configuration is unset.

But I'd be the happiest as you can see if they just flat-out made it throw an exception if it's unset. Having a default config like this would be great for first start and it'd crash on the second start. Never understood why it's there. :thinking:

We set the default configuration because it makes it a lot easier in code snippets and generally picking up Realm for the first time (as you don't have to learn about configurations). So while I have sympathy for the idea, I suspect that more people will get hurt by the change.

We could maybe provide an override for Realm.init() where you specified the default config or null but I suspect that no-one would use it, until they actually hit what you are hitting and then it would be kinda too late anyway.

Hey - looks like you forgot to add a T:* label - could you please add one?

Actually considering you can end up with an incorrect schema mode, I think if you have a local DB config set when you are trying to use Sync, this is masking a very fatal error and now you also have to mess around with deleting the local file you didn't even intend to create 馃

While I understand that you want to get started quickly. I still strongly disagree.

I suspect most people that have real use cases will have to use something other than the default configuration provided by realm init right? If you need migrations, which you probably will for local realms or if you use a realm cloud it is not a valid configuration.

In my case, this has led to a high number of crashes in production. Yes, it was my fault I didn't set my own configuration in Application.onCreate(). It worked fine when the app was stared normally, but whenever the app was restored from being killed in the background and then restarted I would get "provided schema version 0 is less than last set version", which is very confusing. It took me months to figure out that this was due to Realm.init setting a default configuration and that my own default configuration was set too late.

I'd argue that for most production use cases, setting the Realm default configuration in Realm.init() is not a good idea. But if it won't be changed, at least it would be good if the error message could be a bit more clear?

@Zhuinden I guess that when trying to migrate a local database to a synced one it also leads to confusion. I can't just check if a local database file exists. I also needs to check if it is empty?

If you're trying to "migrate a local database" it's done by Realm.getInstance(config) (or Realm.getDefaultInstance() and opening the Realm will fail with RealmMigrationNeededException.

The only way to manually force this is to open the Realm as a DynamicRealm and check if its schema version is lower than the one you intend to create, CLOSE the dynamic realm and THEN call Realm.migrateRealm().

@Zhuinden bad choice of words from my end. I have a local app now, but want to copy the data over to a synced realm if it has data and then delete the local realm when it is done.

Was this page helpful?
0 / 5 - 0 ratings