Realm Xamarin v10.10.0 Release Notes

Release Date: 2022-02-28 // about 2 years ago
  • Guid representation issue

    ๐Ÿš€ This release fixes a major bug in the way Guid values are stored in the database. It provides an automatic migration for local (non-synchronized) databases, but extra caution is needed when upgrading an app that uses Sync.

    Context

    ๐Ÿ‘€ A Guid is represented by 4 components - int, short, short, and a byte[8]. Microsoft's Guids diverge from the UUID spec in that they encode the first three components with the endianness of the system (little-endian for all modern CPUs), while UUIDs encode their components as big-endian. The end result is that the same bytes have a different string representations when interpreted as a Guid by the .NET SDK vs when interpreted as a UUID by the Realm Database - e.g. f2952191-a847-41c3-8362-497f92cb7d24 vs 912195f2-47a8-c341-8362-497f92cb7d24 (note the swapping of bytes in the first three components). You can see the issue by opening a database created by the .NET SDK in Realm Studio and inspecting the values for Guid properties.

    ๐Ÿ›  Fix

    ๐Ÿ”€ The fix we're providing is to adjust the behavior of the .NET SDK to read/write Guids to the database with big-endian representation. This means that the SDK and the database will consistently display the same values. This has some implications which are described in the Local- and Synchronized Realms sections.

    Local Realms

    โšก๏ธ For local Realms, we're executing a one-time migration the first time the Realm is opened with the new SDK. During this migration, we'll update all Guid fields to big-endian format. This means that their string representation will remain the same, but the value in the database will change to match it. This means that the upgrade process should be seamless, but if you decide to downgrade to an older version of the SDK, you'll see the byte order get flipped. The migration will not execute multiple times, even if you downgrade.

    ๐Ÿ”€ Synchronized Realms

    ๐Ÿ”€ There's no client migration provided for synchronized Realms. This is because the distributed nature of the system would mean that there will inevitably be a period of inconsistent state. Instead, the values of the Guid properties are read as they're already stored in the database, meaning the string representation will be flipped compared to previous versions of the SDK but it will now match the representation in Atlas/Compass/Realm Studio. There are three general groups your app will fall under:

    • If you don't care about the string values of Guid properties on the client, then you don't need to do anything. The values will still be unique and valid Guids.
    • โฌ†๏ธ If you do use the string guid values from the client app - e.g. to correlate user ids with a CMS, but have complete control over your client devices - e.g. because this an internal company app, then it's advised that you execute a one-time migration of the data in Atlas and force all users to upgrade to the latest version of the app.
    • โšก๏ธ If you can't force all users to update at the same time, you can do a live migration by adding an extra property for each Guid property that you have and write a trigger function that will migrate the data between the two. The old version of the app will write to the original property, while the new version will write to the new property and the trigger will convert between the two.

    โšก๏ธ If you are using sync and need to update to the latest version of the SDK but are not ready to migrate your data yet, see the Opting out section.

    Opting out

    ๐Ÿ›  If for some reason, you want to opt out of the fixed behavior, you can temporarily opt out of it by setting the Realm.UseLegacyGuidRepresentation property to true. This is not recommended but can be used when you need more time to test out the migration while still getting bugfixes and other improvements. Setting it to true does two things:

    1. It brings back the pre-10.10.0 behavior of reading/writing Guid values with little-endian representation. โช 1. It disables the migration code for local Realms. Note that it will not revert the migration if you already opened the Realm file when UseLegacyGuidRepresentation was set to false.

    โœจ Enhancements

    • Lifted a limitation that would prevent you from changing the primary key of objects during a migration. It is now possible to do it with both the dynamic and the strongly-typed API: csharp var config = new RealmConfiguration { SchemaVersion = 5, MigrationCallback = (migration, oldVersion) => { // Increment the primary key value of all Foos foreach (var obj in migration.NewRealm.All<Foo>()) { obj.Id = obj.Id + 1000; } } }
    • ๐Ÿšš [Unity] The Realm menu item in the Unity Editor was moved to Tools/Realm to reduce clutter and align with other 3rd party editor plugins. (Issue #2807)

    ๐Ÿ›  Fixed

    • ๐Ÿ›  Fixed an issue with xUnit tests that would cause System.Runtime.InteropServices.SEHException to be thrown whenever Realm was accessed in a non-async test. (Issue #1865)
    • ๐Ÿ›  Fixed a bug that would lead to unnecessary metadata allocation when freezing a realm. (Issue #2789)
    • ๐Ÿ›  Fixed an issue that would cause Realm-managed objects (e.g. RealmObject, list, results, and so on) allocated during a migration block to keep the Realm open until they are garbage collected. This had subtle implications, such as being unable to delete the Realm shortly after a migration or being unable to open the Realm with a different configuration. (PR #2795)
    • ๐Ÿ›  Fixed an issue that prevented Unity3D's IL2CPP compiler to correctly process one of Realm's dependencies. (Issue #2666)
    • ๐Ÿ›  Fixed the osx runtime path in the Realm NuGet package to also apply to Apple Silicon (universal) architectures (Issue #2732)

    Compatibility

    • Realm Studio: 11.0.0 or later.

    Internal

    • Using Core 11.10.0