Synced Fine-Grained Permissions and Local Realm – what is the best practice for models?


#1

In my solution there are 2 types of users, fist only using Local Realm, second using Synced Realm. Users can change their type from one to another.

Synced realm using Object-level Fine-Grained Permissions, so example model class is:

public class Dog : RealmObject
{
 public string Name { get; set; }

 public IList<Permission> Permissions { get; }
}

The problem is that I can’t use the same model for Local Realm, because of the RealmException

Property ‘Dog.Permissions’ of type ‘array’ has unknown object type ‘__Permission’

I understand the reason but what is the best way to solve it? Do I need to create local version of each model class, or there is a better way?


#2

@Radek Local non-synced Realms do not have a concept of permissions - that is for sharing data using our Sync protocol. When you share data - you need a way to restrict the pool of data to a smaller subset. I am not sure if we ever considered this use case. Why do you need this?


#3

@ianward Thank you for your answer. In my case, I don’t need permissions for non-synced Realm. I just need design advice. Am I right, that the best way is to have interface and separate class for synced and non-synced Realm? So for example

public interface IDog
{
 string Name { get; set; }
}

public class SyncDog : RealmObject, IDog
{
 public string Name { get; set; }

 public IList<Permission> Permissions { get; }
}

public class LocalDog : RealmObject, IDog
{
 public string Name { get; set; }
}

Or maybe there is any better idea?

Following the question, I found that you created very useful script (https://realm.io/docs/cookbook/js/local-realm-to-synced/) but if I’m not wrong, it works only with Path-level Permissions. Do you have maybe something similar (the best would be c# version) to copy from non-synced Realm to fine-grained permissions synced Realm (and back)? I can imagine that in this case it will be more complicated because permissions information and different schema but maybe it is already solved.


#4

@ianward I noticed that in real life situation (with relationships) this idea with interfaces do not works because of the error

Fody/RealmWeaver: SyncShip.Captain is a ‘Repository.ICaptian’ which is not yet supported.

It seems to be impossible to use interfaces and it is necessary to have separate classes for sync and non-sync Realm. Is there any way to get around this problem without tons of duplicated code?


#5

You can add the __Permission object to your non-synced Realm’s schema. It’s excluded by default, but there’s nothing to stop you from adding it:

var config = new RealmConfiguration // <-- non-synced config
{
    ObjectClasses = new[]
    {
        typeof(ClassPermission),
        typeof(Permission),
        typeof(PermissionRole),
        typeof(PermissionUser),
        typeof(RealmPermission),
        // Rest of your app's classes
    }
};

You don’t need this for the sync version of your Realm because we’ll add them automatically.


#6

@nirinchev Thank you very much. It works like a charm.


#7

How do you do this in Java?


#8

A few use-cases come to mind. When converting between local and synced realms, local unit tests. I am upgrading a local app to a synced app and want to roll out the changes gradually and in this case it would be very useful to be able to run the same classes both for the local and the synced realm.

I just added permissions, and now all my unit tests, which are based on local realms, fail.


#9

Changed my strategy and left the objects in the local configuration unchanged. Instead I added a root user object that is only used in the sync configuration, and I applied the permissions to this object instead. Should work!