Problems with syncing Realm with Atlas - .NET SDK

Hi,

I am starting my adventure with Mongo Realm yet I have encountered some problems. This is my first post and I am not entirely sure if I should post this kind of issue here. I have created Xamarin.Forms app in Visual Studio installed the Nuget for the realm and tried to connect to my RealmApp via sync. I am debugging my app on my phone and as long as the connection establishes, everything is fine but write operations upload records only to local Realm and not syncing . Also, query operations do not return this one little record I written to atlas :confused: Here are some parts of the code and screenshots of the problem.

private async void OnLoginClicked(object obj)
        {          
            var app = Realms.Sync.App.Create("larpapp-wiqbj");
            var user = await app.LogInAsync(Credentials.Anonymous());
            var config = new SyncConfiguration("_partitionKey", user);

            using (var realm = Realm.GetInstance(config))
            {              
                var someUsers = realm.All<Models.User>();
                foreach (Models.User someUser in someUsers)
                {
                    await App.Current.MainPage.DisplayAlert(someUser.Email, someUser.Username, someUser.Password);
                }
            }        
        }

What could be a potential problem here? Should I explicitly enable realm syncing in some secondary thread? If so, how to do it?

Thanks for any kind response :slight_smile: :innocent:

Hi @Przemek_Grobecki and welcome to the forum! :slight_smile:

What I’d suggest to change here is

var realm = Realm.GetInstance(config)

to

var realm = await Realm.GetInstanceAsync(config)

similar to what you did with the login. This should make sure you wait for the Realm to be opened.

If that’s not enough to immediately query the Realm you can also add

await realm.GetSession().WaitForDownloadAsync();

You can find those two examples and more at https://docs.mongodb.com/realm/sdk/dotnet/examples/sync-changes-between-devices/

Let me know if it works or you have any other questions. :+1:

Best,
Dominic

Hello @Dominic_Frei and thank You for your response! :grinning_face_with_smiling_eyes:

Unfortunately, the method now throws:

Realms.Exceptions.RealmException: ‘A system error occurred while opening a Realm. See InnerException for more details.’ Source=mscorlib

Stack trace:

at Realms.Sync.SyncConfiguration.CreateRealmAsync (Realms.Schema.RealmSchema schema, System.Threading.CancellationToken cancellationToken) [0x0011d] in C:\jenkins\workspace\realm_realm-dotnet_PR-2497\Realm\Realm\Configurations\SyncConfiguration.cs:194
at larpAppBlank.ViewModels.LoginViewModel.OnLoginClicked (System.Object obj) [0x000ec] in D:\Thesis\LarpApp\playground\larpAppBlank\larpAppBlank\larpAppBlank\ViewModels\LoginViewModel.cs:28
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
at Android.App.SyncContext+<>c__DisplayClass2_0.b__0 () [0x00000] in /Users/builder/azdo/_work/2/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36
at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in /Users/builder/azdo/_work/2/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36
at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/builder/azdo/_work/2/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-30/mcw/Java.Lang.IRunnable.cs:90
at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.39(intptr,intptr)

I can’t pinpoint the problem from this stack trace alone.

Would you be able to share some more code with us?
That whole class might be helpful, maybe even more.

If that’s not openly sharable I can also provide you with other options to keep your code private if you prefer that.

It is nothing private… at least yet :grin:
Here is Github link:

Ah, perfect. Thank you for that!

I’ve run it locally and can 100% reproduce your problem.

To make it a bit easier to read I’ve updated the LoginViewModel to print the error:

using Realms;
using Realms.Sync;
using System;
using Xamarin.Forms;

namespace realmBlank.ViewModels
{
    class LoginViewModel : BaseViewModel
    {
        public Command LoginCommand { get; }

        public LoginViewModel()
        {
            Title = "LoginPage";
            LoginCommand = new Command(OnLoginClicked);
        }

        private async void OnLoginClicked(object obj)
        {
            var app = Realms.Sync.App.Create("larpapp-wiqbj");
            var user = await app.LogInAsync(Credentials.Anonymous());
            var config = new SyncConfiguration("_partitionKey", user);
            try
            {
                using (var realm = await Realm.GetInstanceAsync(config))
                {
                    var someUsers = realm.All<Models.User>();
                    foreach (Models.User someUser in someUsers)
                    {
                        await App.Current.MainPage.DisplayAlert(someUser.Email, someUser.Username, someUser.Password);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                throw;
            }
        }
    }
}

But you might as well just set a breakpoint and look at the inner error (which is the one raised by our Core framework, not the .NET SDK - we print them out as well to make your debugging as easy as possible).
It’s maybe not all to obvious at first but the error in log will then look like this:

Realms.Exceptions.RealmException: A system error occurred while opening a Realm. See InnerException for more details. ---> Realms.Exceptions.RealmException: The following changes cannot be made in additive-only schema mode:
- Property 'User._partitionKey' has been made optional.
- Property 'User.emailAddress' has been made optional.
- Property 'User.password' has been made optional.
- Property 'User.username' has been made optional.
   --- End of inner exception stack trace ---

You have made changes to your model that need to be reflected in Atlas as well.
Since you are still in development I’d recommend turning on development mode so you can easily just do all the schema changes from within your app’s code without having to worry about defining and migrating a schema in Sync / Atlas.

Further documentation for this:

3 Likes

Yes! That was the issue. I did not add [Required] tag to my RealmObject model inherited class properties. Thank You a lot!

1 Like

No problem at all. Glad to hear everything works now. :slight_smile:

1 Like