Custom Conflict Resolution i.e Role based conflict resolution

I want to integrate the conflict resolution for my iOS app.
Let us suppose I have 2 users.
UserA: Admin role
UserB: Normal User

Both the users are updating the same records at the same time in offline mode. User A is updating first then User B is updating the same record when internet is available then changes made by the User A should remain and it should sync to the Altas i.e. it should work opposite to Last Update Wins rule of conflict resolution.

Apart from this I want to maintain the History of the operation performed in the app. How can I maintain the history of the users of a app.
Thanks in advanvce.

Hi, the best way to implement the custom resolution in this way is probably to structure your data as a list. Then you can have the different roles and do different things with the data. IE, the Admin can insert to the front of the list and the Normal user can insert to the back of the list. Then, you also have the history of the changes to this field.

Docs: https://www.mongodb.com/docs/atlas/app-services/sync/details/conflict-resolution/#custom-conflict-resolution

Another way of achieving this is to have the Admin user always fully replace an object (delete it and re-insert it). That will result in the Admin writes always winning.

Let me know if this works.
Tyler

@Tyler_Kaye Could you please help me out via giving sample code for the above approach.
And my next question was after conflicts resolution how we can keep all previous updates in a log that could be viewed as a version history in the application if needed. I’ll be really thank full to you.

Hi,

I, unfortunately, do not have as much time to respond here as I would like ideally and a full code sample might take a bit so I can pseudo-code it here if that works.

There are two things going on. the first is how to have some sort of “audit”. That can be done by storing not just a primitive but also a “list”. Therefore you could have something like this:

type AuditInfo struct {
     UserId string 
     NewValue string
     UpdatedAt Time
}

type Person struct {
    ID ObjectId 
    Age int 
    Name string 
    NameHistory []AuditInfo
}

Now, using the above, if we wanted to capture some sort of “audit” of a person as we change their name, we can update the code to be something like:

realm.write({
    person.Name = "new name" 
    person.AuditInfo.push({
         UserId = "my user", 
         NewValue = "new name", 
         UpdatedAt = time.Now(), 
    })
})

Then you can have the “Name” field represent the name of the person, and if you are interested in observing the history of changes made you can look at the NameHistory field.

Now for the second issue of “how do you structure better semantics for an admin who always wants their writes to win”, you can do something like this to delete the object and re-create it to force its updates to “win”

// For the admin 
realm.write({
     personCopy := person.Copy()
     person.Delete() 
     personCopy.Name = "new name"
     personCopy.Insert()
})

Hope this helps out!
Tyler

Thanks for the reply. My question is can we make Class type object in place of Struct type. i.e in Realm Swift SDK we are creating realm objects in Class type when we are creating Struct type then we are getting error 'wrappedValue’ is unavailable: @Persisted can only be used as a property on a Realm object.

Hi, that seems like an unrelated question (correct me if I am wrong). I do not have familiarity with the Swift SDK but I would recommend creating a new post for this with the proper tags and keywords and it will get routed to the proper team.