Hey, I’m wondering if it’s possible to build a rich text editor that can be edited by multiple users simultaneously (similar to Google Docs).
I believe if you would simply use the String type in Realm, the last update on the string would always win and you could lose text that was entered by the user.
So I thought about using the List type in Realm and representing each character as a list item. But I’m not sure if Realm is able to resolve all conflicts as you would expect it in a text editor. I couldn’t find much about the Operational Transformation algorithm that Realm is using. It was only mentioned once in the documentation at https://docs.realm.io/sync/realm-sync-a-primer/a-simple-example.
Has anyone tried this before? Can Realm be used for this kind of app? Do you have any other ideas on how to implement this?
@Bruno_Joseph Google Doc’s implementation of OT is optimized for substring manipulations of a full-text document, they have built a full application around this implementation whereas Realm’s conflict resolution is more general purpose.
You are correct in your assumption that a String type would merge with the Last update so the substring edits would be lost. Adding a per character List would needlessly tax the OT algorithm and likely result in bizarre merges that might not merge to real words.
We crafted an app very similar to this for internal use/communication. One slight difference is that when a user is ‘editing’ the other users can see live changes but cannot ‘edit’ at the same time.
While it worked, there were a number of concurrency issues (@Ian_Ward comment is on point for sure) and one big issue is the lack of record/row locking in Realm in general. A user can just randomly delete the item being worked on and other users didn’t know about it until after and that obviously created an issue.
We added a feature to ‘lock’ the item being worked on and the other users would observe that ‘lock’ and not allow them to edit. The problem with that was Realm doesn’t offer user presence so if a user was disconnected from the internet, the item would stay ‘locked’. Soft deletes and edits kinda worked but that added a whole other set of code to manage that.
A while back, we submitted a feature request for having some kind of locking feature that would really be ideal for our use case to keep data protected and not be overwritten by changes made by others
but were essentially told we we crazy for even suggesting such a thing as “record locking”. lol.
So, for that specific app, we leveraged Firebase which, because of user presence, gave us the ability to ‘lock’ records and prevent changes, and if a user d/c’s the Firebase server automatically ‘unlocks’ that data.
We think it’s a great idea in general and there would be a market for a non-web based multi-user editor so I would encourage you to take a whack at it and see if you can come up with a different approach.
The “user presence” if very useful feature for collaborative apps even when locking is not needed. MongoDB Atlas supports some kind of triggers. Maybe it would be enough to add some onDisconnect trigger type to the MongoDB Atlas?
@Ondrej_Medek That’s exactly what we attempted to do; Leverage MongoDB Atlas (or Stitch) for this purpose.
Our apps are multi-device, similar to Notes, Reminders or even Messages (iMessage)
from Apple… in other words, a user can start a document on their iPhone, continue working with it on their iPad and then when they get back to the office, work on it on their Mac (macOS).
Unfortunately MongoDB does not support the Macintosh (macOS) platform (with their Swift API) and doesn’t have any intention of adding it (according to their roadmap per engineering) so we had to abandon that plan as well after several months of effort.