-
Type: Bug
-
Resolution: Works as Designed
-
Priority: Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: None
What happened?
I am writing an app where I'll have Anonymous login for general public and Email/Password auth for members. So users should be able to log in and log out, whenever they log out the app should use anonymous user, and when they log in, the app should switch to the logged in user.
However, when I try to implement this logic, after logging in, logging out and then trying to log in again, it produces this error:
Realms.Exceptions.RealmMismatchedConfigException: 'Realm at path '.../database.realm' already opened with different sync user.'
The issue is consistent - it always happens.
I tried to manually call Dispose on realm instance before switching users - didn't help. Maybe I am doing something wrong?
Repro steps
- the app logs in automatically with Anonymous provider, then
- a user logs in with Email/Password. When that happens, app gets a new flexible config with the newly logged in user and uses it to get Realm instances
- when the logged in user decides to log out, I simply call LogOutAsync and then change config back to use the now active anonymous user.
- if I do this 1, 2 times, eventually I get this error:
Realms.Exceptions.RealmMismatchedConfigException: 'Realm at path 'C:\Users\x.dr\source\repos\movsar\chldr\chldr_server\bin\Debug\net6.0\data\database.realm' already opened with different sync user.'
Version
.NET 6
What Atlas Services are you using?
Atlas Device Sync
What type of application is this?
Other
Client OS and version
Windows 10
Code snippets
My RealmService:
public class RealmService { private const string myRealmAppId = "dosham-lxwuu"; private App _app { get; set; } private RealmConfigurationBase _config; internal event Action DatabaseInitialized; internal event Action DatabaseSynced; internal Realm GetRealm() { if (_config == null) { throw new Exception("Config shouldn't be null"); } return Realm.GetInstance(_config); } internal async Task InitializeApp() { Logger.LogLevel = LogLevel.Debug; Logger.Default = Logger.Function(message => { Debug.WriteLine($"APP: Realm : {message}"); }); _app = App.Create(new AppConfiguration(myRealmAppId) { BaseFilePath = FileService.AppDataDirectory, }); var appUser = _app.CurrentUser; // Log in as anonymous user to be able to read data if (appUser?.State != UserState.LoggedIn) { appUser = await _app.LogInAsync(Credentials.Anonymous(true)); } } internal void RefreshRealmConfig(Realms.Sync.User appUser) { _config = GetRealmConfigForSpecifiedUser(appUser); } private RealmConfigurationBase GetRealmConfigForSpecifiedUser(Realms.Sync.User appUser) { if (appUser == null) { throw new Exception("User must not be null"); } return new FlexibleSyncConfiguration(appUser, FileService.DatabasePath) { SchemaVersion = 1, PopulateInitialSubscriptions = (realm) => { Debug.WriteLine($"APP: Realm : PopulateInitialSubscriptions"); realm.Subscriptions.Add(realm.All<Entities.Entry>()); realm.Subscriptions.Add(realm.All<Entities.Language>()); realm.Subscriptions.Add(realm.All<Entities.Phrase>()); realm.Subscriptions.Add(realm.All<Entities.Source>()); realm.Subscriptions.Add(realm.All<Entities.Translation>()); realm.Subscriptions.Add(realm.All<Entities.User>()); realm.Subscriptions.Add(realm.All<Entities.Word>()); } }; } internal App GetApp() { return _app; } }
My DataAccess file:
public class DataAccess : IDataAccess { public Realms.Sync.App App => _realmService.GetApp(); public Realm Database { get { var realm = _realmService.GetRealm(); if (App.CurrentUser.Provider == Credentials.AuthProvider.Anonymous) { // Don't try to sync anything if a legitimate user hasn't logged in realm.SyncSession.Stop(); } return realm; } } public event Action DatabaseInitialized; private RealmService _realmService; public async Task Initialize() { await _realmService.InitializeApp(); _realmService.RefreshRealmConfig(App.CurrentUser); } public DataAccess(FileService fileService, RealmService realmService) { _searchEngine = new MainSearchEngine(this); _realmService = realmService; if (App != null) { return; } fileService.PrepareDatabase(); _realmService.DatabaseInitialized += () => { DatabaseInitialized?.Invoke(); }; Task.Run(async () => await Initialize()); } public async Task LogInEmailPasswordAsync(string email, string password) { var appUser = await App.LogInAsync(Credentials.EmailPassword(email, password)); _realmService.RefreshRealmConfig(appUser); } public async Task LogOutAsync() { await App.CurrentUser.LogOutAsync(); _realmService.RefreshRealmConfig(App.CurrentUser); } }
Stacktrace of the exception/crash you're getting
Realms.Exceptions.RealmMismatchedConfigException HResult=0x80131500 Message=Realm at path 'C:\Users\x.dr\source\repos\movsar\chldr\chldr_server\bin\Debug\net6.0\data\database.realm' already opened with different sync user. Source=Realm StackTrace: at Realms.Sync.SyncConfigurationBase.CreateHandle(RealmSchema schema) at Realms.RealmConfigurationBase.CreateRealm() at Realms.Sync.FlexibleSyncConfiguration.CreateRealm() at chldr_data.Services.RealmService.GetRealm() in C:\Users\x.dr\source\repos\movsar\chldr\chldr_data\Services\RealmService.cs:line 30 at chldr_data.Services.DataAccess.get_Database() in C:\Users\x.dr\source\repos\movsar\chldr\chldr_data\Services\DataAccess.cs:line 24 at chldr_data.Services.DataAccess.<GetCurrentUserInfoAsync>d__14.MoveNext() in C:\Users\x.dr\source\repos\movsar\chldr\chldr_data\Services\DataAccess.cs:line 58 at chldr_shared.Stores.UserStore.<SetCurrentUserInfoAsync>d__17.MoveNext() in C:\Users\x.dr\source\repos\movsar\chldr\chldr_shared\Stores\UserStore.cs:line 64 at chldr_shared.Stores.UserStore.<<LogInEmailPasswordAsync>b__18_0>d.MoveNext() in C:\Users\x.dr\source\repos\movsar\chldr\chldr_shared\Stores\UserStore.cs:line 80 -- Realm output Logs Exception thrown: 'Realms.Exceptions.RealmMismatchedConfigException' in Realm.dll Exception thrown: 'Realms.Exceptions.RealmMismatchedConfigException' in System.Private.CoreLib.dll Exception thrown: 'Realms.Exceptions.RealmMismatchedConfigException' in chldr_shared.dll Exception thrown: 'Realms.Exceptions.RealmMismatchedConfigException' in System.Private.CoreLib.dll An exception of type 'Realms.Exceptions.RealmMismatchedConfigException' occurred in System.Private.CoreLib.dll but was not handled in user code Realm at path 'C:\Users\x.dr\source\repos\movsar\chldr\chldr_server\bin\Debug\net6.0\data\database.realm' already opened with different sync user.
Relevant log output
> [Exception] chldr_data.dll!chldr_data.Services.RealmService.GetRealm() Line 30 C#
[Exception] chldr_data.dll!chldr_data.Services.DataAccess.Database.get() Line 24 C#
[Exception] chldr_data.dll!chldr_data.Services.DataAccess.GetCurrentUserInfoAsync() Line 58 C#
[Exception] chldr_shared.dll!chldr_shared.Stores.UserStore.SetCurrentUserInfoAsync() Line 64 C#
[External Code]
[Waiting on Async Operation, double-click or press enter to view Async Call Stacks]
chldr_shared.dll!chldr_shared.Stores.UserStore.LogInEmailPasswordAsync.AnonymousMethod__18_0() Line 80 C#