MongoDB Realm Schema Updates

Can anyone point me to a guide that explains the step by step procedure that should be used to upgrade the schema in a synced realm.

Thanks
Duncan

OK perhaps I need to qualify this a bit more.

According to the docs online an additive change is automatic.

Additive Changes

Additive changes to a schema are usually optional additions to the schema, such as:

  • adding a class
  • adding an optional (not required) property to an existing class

Additive changes apply automatically to synced realms; you can make these additive schema changes with no additional configuration changes.

So if I want to add an additional text field to a RealmSwift object, such as

@objc dynamic var comment: String?

Then do I have to do anything the MongoDB Realm App’s schema (in the cloud) or can I simply add the additional property to the client’s schema definition.

And then for a non optional property, such as an Int value is it possible to define this as below in the RealmSwift schema object ?

@objc dynamic var intValue: Int = 0

Thanks.

Hi @Duncan_Groenewald ,

It depends: if you have Development Mode active, you only need to change the class in the app, and the change will be reflected in the Realm Schema in the backend. This, however, isn’t advised if the app is already in production: in that case you’ll need to change the Realm Schema first, and deploy the new version of the app with the modified class later. The optionality will guarantee that old versions of the app can safely ignore the new variable.

Yes, you can do that as well, preferably in the Realm Schema on the Portal: the worst case scenario, as with other Destructive Changes, is that the client will receive a Client Reset, and will need to re-download the DB. When you’ll try to apply the changes to the Schema, you’ll usually be notified if a Sync restart (and a Client Reset) is needed.

If your changes are so extensive to compromise the functionality of a previous version of the app (like, removing a whole class), more work is obviously needed.

@Paolo_Manna so is there any documentation describing the step by step sequence of changes that need to be made in the Realm Cloud app, with examples ?

As I understand it for a production app, in the case of an optional STRING value, all one has to do will be the following:

  1. Edit the Realm Schema on the Portal to add the optional string property - no changes required in Atlas database. Is it necessary to stop and restart sync? If so what specifically needs to be done, does one have to terminate sync and re-enable it or can one Pause sync and then restart it ?

  2. Release new version of client application with the additional optional property.

Correct: the advantage of MongoDB is this type of flexibility

No: if the change is a destructive one and requires a Sync termination/re-enable, you’ll be notified in the Schema Editor when you press the Save button

Nothing, really, in that specific case: again, if a Sync cleanup is necessary, you’ll be alerted and given the option to discard the change when you’re saving it.

Exactly: if there’s some change in your logic (i.e., the property is optional, but is expected to have a value in some circumstances), you’ll need to perform a migration for the old data, of course.

Cool that sounds simple enough.

Now what about a property - let’s say an Integer value where we want the to have a default value. Is it possible to define a default in the client schema such that the client side will always see the default value rather than NIL.

For example:

@objc dynamic var someInt: Int = 0

or perhaps

@objc dynamic var someString: String = “default string”

Am I correct in assuming that this won’t work and that one would have to define these optional properties like so:

@objc dynamic var someInt: Int ?

or perhaps

@objc dynamic var someString: String ?

This is not completely correct: if you declare the new properties as non-optional (i.e. required), Realm will provide them with fixed, but non-nil values (empty string and 0 for your example) for the existing objects. If you process the existing documents on the backend in a one-off sweep when you add the new fields, by assigning a different default value, this will be transmitted back to the app. New objects will be created with the default value you set in Swift, obviously.

OK, so I am still a bit unclear as to who this Realm is that will provide the fixed non-nil values for existing objects. Let’s say I set the default in Swift to Int = 1 - for existing objects the property will be 0 (zero) - assuming no backend updates and for new objects (using the new schema) the default will be 1.

For the most part we’re not anticipating anything other than 0 as the default.

I would suggest you update your documentation to explain that NON-OPTIONAL properties can be added as long as you don’t mind that existing objects will have the Realm provided defaults which are empty string or 0.

See the description below.

Additive changes to a schema are usually optional **additions** to the schema, such as:

* adding a class
* adding an optional (not required) property to an existing class

Additive changes apply automatically to synced realms; you can make these additive schema changes with no additional configuration changes.

Perhaps a third such as:

* adding a non-optional property to an existing class with Realm supplied defaults for existing objects (0 for numbers and empty string for strings) and schema defined defaults for new client schema created objects.

Thanks @Duncan_Groenewald,

I’ve forwarded your suggestion to the documentation team, for their consideration

@Paolo_Manna BTW it seems you cannot update the RealmSwift object properties to have a new non-optional value. If I do so then Sync fails immediately on all transactions(even on unrelated objects) with an error indicating that one side is option and the other non-option. If I make the new property optional then it works fine.

@objc dynamic var someString: String = “default string”

This is not completely correct: if you declare the new properties as non-optional (i.e. required), Realm will provide them with fixed, but non- nil values (empty string and 0 for your example) for the existing objects.