realm / realm-dotnet

Realm is a mobile database: a replacement for SQLite & ORMs
https://realm.io
Apache License 2.0
1.26k stars 165 forks source link

Realm doesn't sync #1840

Closed pfedotovsky closed 5 years ago

pfedotovsky commented 5 years ago

Goals

I've set up Realm Cloud and want to sync my local database with Realm Cloud in real time. Specifically, I want to change objects in the cloud realm and see them changed in a local database.

Expected Results

A local (e.g. mobile) database is synchronized with the cloud database.

Actual Results

Changes in cloud database not synchronized with local one.

Steps to Reproduce

  1. Create new instance in Realm cloud
  2. Create new Realm
  3. Create some class and populate it with some data
  4. Implement client that constantly queries the class and logs the results
  5. Change value in Realm Studio (or via C# client)

Code Sample

If I change FirstName in cloud realm, changes are not reflected in local database.

using Realms;

namespace RealmTest
{
    public class Person : RealmObject
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string Id { get; set; }
    }
}
using Realms;
using Realms.Sync;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace RealmTest
{
    public class Program
    {
        public static async Task Main()
        {   
            var realm = await GetAsyncRealm();

            while (true)
            {
                var persons = realm.All<Person>();
                Console.WriteLine(persons.First().FirstName);

                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
        }

        private static async Task<Realm> GetAsyncRealm()
        {
            var realmUrl = new Uri("realms://<realmurl>/synctest");
            var user = await User.LoginAsync(Credentials.UsernamePassword("***", "***", false), new Uri("<realmurl>"));
            var syncConfiguration = new FullSyncConfiguration(realmUrl, user);

            var realm = await Realm.GetInstanceAsync(syncConfiguration);
            return realm;
        }
    }
}

Version of Realm and Tooling

nirinchev commented 5 years ago

The problem is that you're running this on a non-looper thread (one without a synchronization context). This means your local instance can't detect there are changes. You can either call realm.Refresh() in the loop or install a synchronization context via Nito.AsyncEx. You can read more about it in the docs.