Releases: realm/realm-dotnet
11.6.1
11.6.1 (2023-11-17)
Fixed
- Fixed FLX subscriptions not being sent to the server if the session was interrupted during bootstrapping. (Core 13.23.3)
- Fixed FLX subscriptions not being sent to the server if an upload message was sent immediately after a subscription was committed but before the sync client checks for new subscriptions. (Core 13.23.3)
- Fixed application crash with 'KeyNotFound' exception when subscriptions are marked complete after a client reset. (Core 13.23.3)
- A crash at a very specific time during a DiscardLocal client reset on a FLX Realm could leave subscriptions in an invalid state. (Core 13.23.4)
- Fixed an error "Invalid schema change (UPLOAD): cannot process AddColumn instruction for non-existent table" when using automatic client reset with recovery in dev mode to recover schema changes made locally while offline. (Core 13.23.4)
Compatibility
- Realm Studio: 13.0.0 or later.
Internal
- Using Core 13.23.4.
11.6.0
11.6.0 (2023-11-03)
Enhancements
-
Added the
App.EmailPasswordAuth.RetryCustomConfirmationAsync
method to be able to run again the confirmation function on the server for a given email. (Issue #3463) -
Added
User.Changed
event that can be used to notify subscribers that something about the user changed - typically this would be the user state or the access token. (Issue #3429) -
Added support for customizing the ignore attribute applied on certain generated properties of Realm models. The configuration option is called
realm.custom_ignore_attribute
and can be set in a global configuration file (more information about global configuration files can be found in the .NET documentation). The Realm generator will treat this as an opaque string, that will be appended to theIgnoreDataMember
andXmlIgnore
attributes already applied on these members. The attributes must be fully qualified unless the namespace they reside in is added to a global usings file. For example, this is how you would addJsonIgnore
fromSystem.Text.Json
:realm.custom_ignore_attribute = [System.Text.Json.Serialization.JsonIgnore]
(Issue #2579)
-
The Realm source generator will now error out in case a collection in the model classes is assigned to a non-null value either in a property initializer or in a constructor. Realm collections are initialized internally and assigning non-null values to the property is not supported, where the
null!
assignment is only useful to silence nullable reference type warnings, in reality the collection will never be null. (Issue #3455) -
Made WebSocket error logging more verbose when using
AppConfiguration.UseManagedWebSockets = true
. #3459
Fixed
- Added an error that is raised when interface based Realm classes are used with a language version lower than 8.0. At the same time, removed the use of
not
in the generated code, so that it's compatible with a minumum C# version of 8.0. (Issue #3265) - Logging into a single user using multiple auth providers created a separate SyncUser per auth provider. This mostly worked, but had some quirks:
- Sync sessions would not necessarily be associated with the specific SyncUser used to create them. As a result, querying a user for its sessions could give incorrect results, and logging one user out could close the wrong sessions.
- Existing local synchronized Realm files created using version of Realm from August - November 2020 would sometimes not be opened correctly and would instead be redownloaded.
- Removing one of the SyncUsers would delete all local Realm files for all SyncUsers for that user.
- Deleting the server-side user via one of the SyncUsers left the other SyncUsers in an invalid state.
- A SyncUser which was originally created via anonymous login and then linked to an identity would still be treated as an anonymous users and removed entirely on logout.
(Core 13.21.0)
- If a user was logged out while an access token refresh was in progress, the refresh completing would mark the user as logged in again and the user would be in an inconsistent state (Core 13.21.0).
- If querying over a geospatial dataset that had some objects with a type property set to something other than 'Point' (case insensitive) an exception would have been thrown. Instead of disrupting the query, those objects are now just ignored. (Core 13.21.0)
- Receiving a write_not_allowed error from the server would have led to a crash. (Core 13.22.0)
- Updating subscriptions did not trigger Realm autorefreshes, sometimes resulting in async refresh hanging until another write was performed by something else. (Core 13.23.1)
- Fix interprocess locking for concurrent realm file access resulting in a interprocess deadlock on FAT32/exFAT filesystems. (Core 13.23.1)
Compatibility
- Realm Studio: 13.0.0 or later.
Internal
- Using Core 13.20.1.
11.5.0
11.5.0 (2023-09-15)
Enhancements
- Streamlined some of the error codes reported in
SessionException
. A few error codes have been combined and some have been deprecated since they are no longer reported by the server. (Issue #3295)
Fixed
- Fixed the message of the
MissingMemberException
being thrown when attempting to access a non-existent property with the dynamic API. (PR #3432) - Fixed a
Cannot marshal generic Windows Runtime types with a non Windows Runtime type as a generic type argument
build error when using .NET Native. (Issue #3434, since 11.4.0)
Compatibility
- Realm Studio: 13.0.0 or later.
Internal
- Using Core x.y.z.
11.4.0
11.4.0 (2023-08-16)
Enhancements
- Added
IQueryable.SubscribeAsync
API as a shorthand for usingSubscriptionSet.Add
. It is a syntax sugar that roughly translates to:It offers a parameter to control whether to wait every time for synchronization or just the first time a subscription is added, as well as cancellation token support. (PR #3403)realm.Subscriptions.Update(() => { realm.Subscriptions.Add(query); }); await realm.Subscriptions.WaitForSynchronization(); // This can now be expressed as await query.SubscribeAsync();
- Added an optional
cancellationToken
argument toSession.WaitForDownloadAsync/WaitForUploadAsync
. (PR #3403) - Added an optional
cancellationToken
argument toSubscriptionSet.WaitForSynchronization
. (PR #3403) - Fixed a rare corruption of files on streaming format (often following compact, convert or copying to a new file). (Core 13.17.1)
- Trying to search a full-text indexes created as a result of an additive schema change (i.e. applying the differences between the local schema and a synchronized realm's schema) could have resulted in an IllegalOperation error with the error code
Column has no fulltext index
. (Core 13.17.1) - Sync progress for DOWNLOAD messages from server state was updated wrongly. This may have resulted in an extra round-trip to the server. (Core 13.17.1)
- Added option to use managed WebSockets (
System.Net.WebSockets.ClientWebSocket
) instead of Realm's built-in WebSocket client for Sync traffic. Managed WebSockets offer improved support for proxies and firewalls that require authentication. This feature is currently opt-in and can be enabled by settingAppConfiguration.UseManagedWebSockets
to true. Managed WebSockets will become the default in a future version. (PR #3412). - Fixed an issue that would make
realm.SyncSession
garbage collected even when there are subscribers torealm.SyncSession.PropertyChanged
.
Fixed
- Fixed a race condition between canceling an async write transaction and closing the Realm file, which could result in an
ObjectDisposedException : Safe handle has been closed
being thrown. (PR #3400) - Fixed an issue where in the extremely rare case that an exception is thrown by
Realm.RefreshAsync
, that exception would have been ignored andfalse
would have been returned. (PR #3400) - Fixed the nullability annotation of
SubscriptionSet.Find
to correctly indicate thatnull
is returned if the subscription doesn't exist in the subscription set. (PR #3403) - Fixed an issue where executing
Filter
queries using remapped properties would only work with the native name rather than the managed one. Now both will work - e.g.:(Issue #3149)partial class MyModel : IRealmObject { [MapTo("Bar")] public int Foo { get; set; } } // Both of these are valid now realm.All<MyModel>().Filter("Foo > 5"); realm.All<MyModel>().Filter("Bar > 5");
Compatibility
- Realm Studio: 13.0.0 or later.
Internal
- Using Core 13.17.1
11.3.0
11.3.0 (2023-07-26)
Breaking Changes
AppConfiguration.LocalAppName
andAppConfiguration.LocalAppVersion
have been deprecated and will be removed in a future version. They have never had an effect as the values supplied by the SDK was never sent to the server. (PR #3387)
Enhancements
- Added
App.BaseFilePath
,App.BaseUri
, andApp.Id
properties that return the values supplied inAppConfiguration
. (PR #3385) - Added
AppConfiguration.UseAppCache
property that controls whether theApp
instance returned fromApp.Create
should be cached or not. The general recommendation is to not set it (i.e. leave the default value oftrue
), but it can be useful when writing unit tests. (Issue #3382).
Fixed
- Fixed a Unity Editor crash when the domain is reloaded while a
Realm.GetInstanceAsync
operation is in progress. (Issue #3344) - Fixed the implementation
App.Equals
andApp.GetHashCode
to return correct results, particularly when theApp
instance is cached. (PR #3385) - Fixed an issue where building for Android on Unity would fail with "Could not analyze the user's assembly. Object reference not set to an instance of an object". (Issue #3380)
- A GeoBox is now just a shortcut for the equivilent GeoPolygon. This provides consistent query results and error checking. (Core 13.15.2)
- Fixed several corner cases (eg. around the poles) where invalid points matched a geoWithin query. (Core 13.15.2)
- Fixed an error during async open and client reset if properties have been added to the schema. This fix applies to PBS to FLX migration if async open is used. (Core 13.16.1)
Compatibility
- Realm Studio: 13.0.0 or later.
Internal
- Using Core 13.17.0
11.2.0
11.2.0 (2023-07-07)
Enhancements
- Added validation checks to the geospatial type constructors. This means that an exception will now be thrown when constructing an invalid geospatial shape rather than when using it in a query. (PR #3362)
- Relaxed some validations when invoking
IndexOf(null)
on a collection of non-nullable types. Previously, this would throw anArgumentNullException
whereas now it will return-1
. This is particularly useful for data-binding scenarios where the binding engine might invoke it asIndexOf(SelectedItem)
which would throw an exception whenSelectedItem
isnull
. (PR #3369) - Changed
RealmSet.IndexOf
implementation to return the actual result rather than throw aNotSupportedException
. The order of persisted sets is still non-deterministic, but is stable between write transactions. Again, this is mostly useful for data-binding scenarios where the set is passed as a binding context to a collection control. (PR #3369)
Fixed
- Fixed an issue on Unity on Windows when the weaver would trigger excessive terminal windows to open. (Issue #3364
- Fixed an issue on Unity on CI where weaving would fail with the following error:
Could not analyze the user's assembly. Cannot access a closed Stream.
. (Issue #3364 - Fixed a
NullReferenceException
when weaving classes on Unity in batch mode. (Issue #3363)
Compatibility
- Realm Studio: 13.0.0 or later.
Internal
- Using Core 13.15.0
11.1.2
11.1.1
11.1.1 (2023-06-19)
Fixed
- Fixed a namespacing issue that would cause Unity projects to fail to build due to
'Realm' is a namespace but is used like a type
. (Issue #3351) - Improved the warning message when adding Realm attributes on a non-persisted property. (Issue #3352)
Compatibility
- Realm Studio: 13.0.0 or later.
Internal
- Using Core 13.15.0.
11.1.0
11.1.0 (2023-06-17)
Enhancements
- Deprecate the
Realm.SourceGenerator
andRealm.Fody
packages. The source generation and weaver assemblies are now contained in the mainRealm
package. This should be a transparent change for users who only referenced theRealm
package, but if you explicitly added a package reference toRealm.SourceGenerator
orRealm.Fody
, you should remove it. (PR #3319) - Automatically handle
RealmObject
->EmbeddedObject
migrations by duplicating objects referenced by multiple parents as well as removing "orphaned" objects. (Issue #2408) - New notifiers can now be registered in write transactions until changes have actually been made in the write transaction. This makes it so that new notifications can be registered inside change notifications triggered by beginning a write transaction (unless a previous callback performed writes). (Core 13.10.1)
- Partition-Based to Flexible Sync Migration for migrating a client app that uses partition based sync to use flexible sync under the hood if the server has been migrated to flexible sync is officially supported with this release. Any clients using an older version of Realm (including the original support released in Core 11.0.0) will receive a "switch to flexible sync" error message when trying to sync with the app. (Core 13.11.0)
- Support sort/distinct based on values from a dictionary e.g.
.Filter("TRUEPREDICATE SORT(meta['age'])")
. (Core 13.14.0) - Added initial support for geospatial queries on points. (Issue #3299)
- In this version, only queries of the form "is this point contained in this shape" (equivalent to $geoWithin in MongoDB) are supported.
- There is no index support right now.
- There is no dedicated type for persisted geospatial points. Instead, points should be stored as GeoJson-shaped embedded object and queries will use duck-typing to check if the shape contains the object. For convenience, here's an example embedded object that you can use in lieu of a Realm-provided dedicated type:
public partial class Location : IEmbeddedObject { // The coordinates and type properties are mandatory but may be private. // You can add more fields if necessary - those will be ignored when doing // geospatial queries. [MapTo("coordinates")] private IList<double> Coordinates { get; } = null!; [MapTo("type")] private string Type { get; set; } = "Point"; public double Latitude => Coordinates.Count > 1 ? Coordinates[1] : throw new Exception($"Invalid coordinate array. Expected at least 2 elements, but got: {Coordinates.Count}"); public double Longitude => Coordinates.Count > 1 ? Coordinates[0] : throw new Exception($"Invalid coordinate array. Expected at least 2 elements, but got: {Coordinates.Count}"); public Location(double latitude, double longitude) { // According to the GeoJson spec, longitude must come first in the // coordinates array. Coordinates.Add(longitude); Coordinates.Add(latitude); } } // Example usage public partial class Company : IRealmObject { public Location Location { get; set; } }
- Three new shape types and one helper point type are added to allow you to check for containment:
GeoPoint
: a building block for the other shape types - it cannot be used as a property type on your models and is only intended to construct the other shape types. It can be constructed implicitly from a value tuple of latitude and longitude:var point = new GeoPoint(latitude: 12.345, longitude: 67.890); var point = (12.345, 67.890);
GeoCircle
: a shape representing a circle on a sphere constructed from a center and radius:var circle = new GeoCircle(center: (12.34, 56.78), radius: 10); // radius in radians var circle = new GeoCircle((12.34, 56.78), Distance.FromKilometers(10));
GeoBox
: a shape representing a box on a sphere constructed from its bottom left and top right corners:var box = new GeoBox((12.34, 56.78), (15.34, 59.78));
GeoPolygon
: an arbitrary polygon constructed from an outer ring and optional holes:var polygon = new GeoPolygon((10, 10), (20, 20), (0, 20), (10, 10)); // a triangle with no holes var outerRing = new GeoPoint[] { (10, 10), (20, 20), (0, 20), (10, 10) }; var hole1 = new GeoPoint[] { (1, 1), (2, 2), (0, 2), (1, 1) }; var hole2 = new GeoPoint[] { (5, 5), (6, 6), (4, 6), (5, 5) }; var polygon = new GeoPolygon(outerRing, hole1, hole2); // A triangle with two smaller triangular holes
- Querying can be done either via LINQ or RQL:
var matches = realm.All<Company>().Where(c => QueryMethods.GeoWithin(c.Location, circle)); var matches = realm.All<Company>().Filter("Location GEOWITHIN $0", circle);
- Support sort/distinct based on values from a dictionary e.g.
realm.All<MyModel>().Filter("TRUEPREDICATE SORT(meta['age'])")
. (Core 13.14.0) - Fixed a potential crash when opening the realm after failing to download a fresh FLX realm during an automatic client reset. (Core 13.14.0)
Fixed
- Fixed a fatal error (reported to the sync error handler) during client reset (or automatic PBS to FLX migration) if the reset has been triggered during an async open and the schema being applied has added new classes. (Core 13.11.0)
- Full text search would sometimes find words where the word only matches the beginning of the search token. (Core 13.11.0)
- We could crash when removing backlinks in cases where forward links did not have a corresponding backlink due to corruption. We now silently ignore this inconsistency in release builds, allowing the app to continue. (Core 13.12.0)
IDictionary<string, IRealmObject?>
would expose unresolved links rather than mapping them to null. In addition to allowing invalid objects to be read from Dictionaries, this resulted in queries on Dictionaries sometimes having incorrect results. (Core 13.12.0)- Access token refresh for websockets was not updating the location metadata. (Core 13.13.0)
- Using both synchronous and asynchronous transactions on the same thread or scheduler could hit the assertion failure "!realm.is_in_transaction()" if one of the callbacks for an asynchronous transaction happened to be scheduled during a synchronous transaction. (Core 13.13.0)
- Fixed a potential crash when opening the realm after failing to download a fresh FLX realm during an automatic client reset. (Core 13.14.0)
- Setting a property containing an embedded object to the same embedded object used to throw an exception with the text
Can't link to an embedded object that is already managed
. Now it is a no-op instead. (Issue #3262)
Compatibility
- Realm Studio: 13.0.0 or later.
Internal
- Using Core 13.15.0.
- Overhauled and extended the metrics collection of the SDK to better drive future development effort. (PR #3209)
11.0.0
11.0.0 (2023-05-08)
Breaking changes
- The
error
argument inNotificationCallbackDelegate
andDictionaryNotificationCallbackDelegate
used in*collection*.SubscribeForNotifications
has been removed. It has been unused for a long time, since internal changes to the database made it impossible for errors to occur during notification callbacks. (Issue #3014) - Removed
RealmObjectBase.GetBacklinks
- insteadRealmObjectBase.DynamicApi.GetBacklinksFromType
should be used. (Issue #2391) - Removed
Realm.DynamicApi.CreateObject(string, object)
and replaced it with more specialized overloads:RealmObjectBase.DynamicApi.CreateObject(string)
can be used to create an object without a primary key.RealmObjectBase.DynamicApi.CreateObject(string, string/long?/ObjectId?/Guid?)
can be used to create an object with a primary key of the corresponding type.
- The API exposed by
Realm.DynamicApi
no longer returndynamic
, instead opting to return concrete types, such asIRealmObject
,IEmbeddedObject
, and so on. You can still cast the returned objects todynamic
and go through the dynamic API, but that's generally less performant than using the string-based API, such asIRealmObjectBase.DynamicApi.Get/Set
, especially on AOT platforms such as iOS or Unity. (Issue #2391) - Removed
Realm.WriteAsync(Action<Realm>)
in favor ofRealm.WriteAsync(Action)
. The newWriteAsync
method introduced in 10.14.0 is more efficient and doesn't require reopening the Realm on a background thread. While not recommended, if you prefer to get the old behavior, you can write an extension method like:(PR #3234)public static async Task WriteAsync(this Realm realm, Action<Realm> writeAction) { await Task.Run(() => { using var bgRealm = Realm.GetInstance(realm.Config); bgRealm.Write(() => { writeAction(bgRealm); }); }); await realm.RefreshAsync(); }
- Removed
InMemoryConfiguration.EncryptionKey
. It was never possible to encrypt in-memory Realms and setting that property would have resulted in runtime errors. (PR #3236) - Removed
SyncConfiguration
- usePartitionSyncConfiguration
orFlexibleSyncConfiguration
instead. (PR #3237) - Removed
Realm.GetSession
- useRealm.SyncSession
instead. (PR #3237) - Removed
DiscardLocalResetHandler
- useDiscardUnsyncedChangedHandler
instead. (PR #3237) - Removed
Session.SimulateClientReset
extensions. These didn't work with automatic reset handlers and were more confusing than helpful. (PR #3237) - Removed
AppConfiguration.CustomLogger
andAppConfiguration.LogLevel
- useLogger.Default
andLogger.LogLevel
instead. (PR #3238) - Removed
RealmConfigurationBase.ObjectClasses
- useRealmConfigurationBase.Schema
instead. (PR #3240) - Removed
ObjectSchema.IsEmbedded
- useObjectSchema.BaseType
instead. (PR #3240) - Removed
ObjectSchema.Builder.IsEmbedded
- useObjectSchema.Builder.RealmSchemaType
instead. (PR #3240) - Removed
ObjectSchema.Builder(string name, bool isEmbedded = false)
- useBuilder(string name, ObjectSchemaType schemaType)
instead. (PR #3240) - Removed
RealmSchema.Find
- useRealmSchema.TryFindObjectSchema
instead. (PR #3240) - Removed
User.GetPushClient
as it has been deprecated in Atlas App Services - see https://www.mongodb.com/docs/atlas/app-services/reference/push-notifications/. (PR #3241) - Removed
SyncSession.Error
event - useSyncConfigurationBase.OnSessionError
when opening a Realm instead. (PR #3241) - Removed the parameterless constructor for
ManualRecoveryHandler
- use the one that takes a callback instead. (PR #3241) RealmValue.AsString
will now throw an exception if the value containsnull
. If you want to get a nullable string, useAsNullableString
. (PR #3245)RealmValue.AsData
will now throw an exception if the value containsnull
. If you want to get a nullablebyte[]
, useAsNullableData
. (PR #3245)RealmValue.AsRealmObject
will now throw an exception if the value containsnull
. If you want to get a nullable string, useAsNullableRealmObject
. (PR #3245)Realm.SyncSession
will now throw an error if the Realm is not opened with aPartitionSyncConfiguration
orFlexibleSyncConfiguration
- before it used to returnnull
. (PR #3245)Realm.Subscriptions
will now throw an error if the Realm is not opened with aFlexibleSyncConfiguration
- before it used to returnnull
. (PR #3245)- Removed
PermissionDeniedException
as it was no longer possible to get it. (Issue #3272) - Removed some obsolete error codes from the
ErrorCode
enum. All codes removed were obsolete and no longer emitted by the server. (PR 3273) - Removed
IncompatibleSyncedFileException
as it was no longer possible to get it. (Issue #3167) - The
Realms.Schema.Property
API now useIndexType
rather than a boolean indicating whether a property is indexed. (Issue #3281) - The extension methods in
StringExtensions
(Like
,Contains
) are now deprecated. Use the identical ones inQueryMethods
instead - e.g.realm.All<Foo>().Where(f => f.Name.Like("Mic*l"))
would need to be rewritten likerealm.All<Foo>().Where(f => QueryMethods.Like(f.Name, "Mic*l"))
.
Enhancements
- Added nullability annotations to the Realm assembly. Now methods returning reference types are correctly annotated to indicate whether the returned value may or may not be null. (Issue #3248)
- Replacing a value at an index (i.e.
myList[1] = someObj
) will now correctly raiseCollectionChange
notifications with theReplace
action. (Issue #2854) - It is now possible to change the log level at any point of the application's lifetime. (PR #3277)
- Some log messages have been added to the Core database. Events, such as opening a Realm or committing a transaction will now be logged. (Issue #2910)
- Added support for Full-Text search (simple term) queries. (Issue #3281)
- To enable FTS queries on string properties, add the
[Indexed(IndexType.FullText)]
attribute. - To run LINQ queries, use
QueryMethods.FullTextSearch
:realm.All<Book>().Where(b => QueryMethods.FullTextSearch(b.Description, "fantasy novel"))
. - To run
Filter
queries, use theTEXT
operator:realm.All<Book>().Filter("Description TEXT $0", "fantasy novel")
.
- To enable FTS queries on string properties, add the
- Performance improvement for the following queries (Core 13.8.0):
- Significant (~75%) improvement when counting (
IQueryable.Count()
) the number of exact matches (with no other query conditions) on a string/int/UUID/ObjectID property that has an index. This improvement will be especially noticiable if there are a large number of results returned (duplicate values). - Significant (~99%) improvement when querying for an exact match on a
DateTimeOffset
property that has an index. - Significant (~99%) improvement when querying for a case insensitive match on a
RealmValue
property that has an index. - Moderate (~25%) improvement when querying for an exact match on a Boolean property that has an index.
- Small (~5%) improvement when querying for a case insensitive match on a
RealmValue
property that does not have an index. - Moderate (~30%) improvement of equality queries on a non-indexed
RealmValue
.
- Significant (~75%) improvement when counting (
- Enable multiple processes to operate on an encrypted Realm simultaneously. (Core 13.9.0)
- Improve performance of rolling back write transactions after making changes. If no notifications events are subscribed to, this is now constant time rather than taking time proportional to the number of changes to be rolled back. Rollbacks when there are notifications subscriptions are 10-20% faster. (Core 13.9.4)
- PBS to FLX Migration for migrating a client app that uses partition based sync to use flexible sync under the hood if the server has been migrated to flexible sync. (Core 13.10.0)
Fixed
- Fixed an issue that could cause a
The specified table name is already in use
exception when creating a new Realm file on multiple threads. (Issue #3302) - Fixed a bug that may have resulted in arrays being in different orders on different devices. Some cases of “Invalid prior_size” may be fixed too. (Core 13.7.1)
- Fixed a crash when querying a
RealmValue
propert...