I cannot synchronize data between MongoDB Atlas cluster and client application

I have a User model in client ios application.

class User: Object {
    @objc dynamic var _id            = ""
    @objc dynamic var _partition     = ""
    @objc dynamic var username       = ""
    @objc dynamic var image          = ""
    @objc dynamic var email          = ""
    @objc dynamic var exp:Int        = 0
    @objc dynamic var level:Int      = 0
    
    override static func primaryKey() -> String? {
        return "_id"
    }
}

I turned dev mode ON, enabled Sync and open realm from client application.
However, the atlas document automatically inserted was incorrect.
User didn’t have “exp” and “level”.

・Creating an object in a realm(I used asyncOpen)

try! realm.write {

    let appUser = User(value: [
            "_id"        : (user!.id)!,
            "_partition" : (user!.id)!,
            "username"   : "NoNameMan",
            "image"      : "https://◯◯◯.jpg",
            "email"      : "sifjeiowojoao@gmail.com",
            "exp"        : Int(0),
            "level"      : Int(0)
        ]
    )

    realm.add(appUser, update: .modified)
}

・Result in Atlsa Cluster

{
 "_id":"aaaaaa11bbbbbb22ccccc33",
 "_partition":"aaaaaa11bbbbbb22ccccc33",
 "email":"sifjeiowojoao@gmail.com",
 "image":"https://◯◯◯.jpg",
 "username":"NoNameMan"
}

I tried to add @objc dynamic var aaa = "" to User model, then opened realm and add a User object.
Then inserted document had “aaa”.

・Result in remote Realm

・Result in Atlsa Cluster

{
 "_id":"aaaaaa11bbbbbb22ccccc33",
 "_partition":"aaaaaa11bbbbbb22ccccc33",
 "aaa":"aaaaa",
 "email":"sifjeiowojoao@gmail.com",
 "image":"https://◯◯◯.jpg",
 "username":"NoNameMan"
}

Why did only datas at Int property fail to synchronize?

There could be a number of explanations. Your objects look fine.

It could be a coding issue - for example the partition value could be incorrect or maybe the objects are not populated correctly. But since that code wasn’t included we don’t know for sure

It could be the server and the client are out of sync - for example if the objects were created without those properties and then they were added. Did you try deleting the local files/clearing the simulator?

Not sure what that correlates to because the first object shown does not have ‘aaa’ and the second does but neither has ‘sample’

Can you clarify the question as it’s a bit confusing.

Sorry, I made a type.
I added some code which will clarify my question.

I tried clearing local simulator and Atlas cluster. Is this all I should do?
I don’t know how to delete local files (and caches?)

I attempted to duplicate the issue but it worked correctly me. I started with a sync’d realm object

class TaskClass: Object {
   @objc dynamic var _id: ObjectId = ObjectId.generate()
   @objc dynamic var _partitionKey: TaskProjectId = ""
   @objc dynamic var name = ""
}

created some objects which sync’d correctly.

Then I added an Int property

class TaskClass: Object {
   @objc dynamic var _id: ObjectId = ObjectId.generate()
   @objc dynamic var _partitionKey: TaskProjectId = ""
   @objc dynamic var name = ""
   @objc dynamic var exp:Int = 0 //added this property
}

Then ran the app again and added a couple more objects and everything wrote, read and sync’d correctly.

There’s still a bit of ambiguity in the question as the first half shows an object in the Atlas cluster that does not contain “exp” and “level” whereas the screen shots show the object schema does include those properties.

Perhaps it’s how you opening your sync’d realm? Or maybe you have multiple clusters or apps?

I’m not very familiar with MongoDB Realm, but my understating is that my architecture consists of three parts; local realm, remote realm and atlas.


Local realm’s object schema includes “exp” and “level”. Remote realm’s schema has them, too. However, atlas doesn’t have them.

I think screenshots show remote realm successfully synchronized with local realm.

I am sure the Mongo folks will jump in but no, that’s not exactly accurate. If you are in this forum, we assume you are using MongoDB Realm which is the product that’s replacing Realm.

At a high level MongoDB Realm stores it’s data in a local container called a Realm and then on the server the data is stored in Atlas. There really isn’t middleman storage as such.

If you log into the online MongoDB Realm Console, the Atlas tab is where your data is and the Realm tab just shows the schema of the objects stored in Atlas. This is why you can have multiple applications access the same Atlas data.

When we attempted to duplicate your issue by creating objects, storing them and then adding properties, that the existing objects that were stored did not have new properties added to them, only the newly added objects. Perhaps that’s what you’re seeing?

@Shi_Miya Are there any error logs in the Logs tab when you attempt to insert the object with the new schema? As Jay said, clearing the local simulator and then terminating sync and re-enabling should reset your state back to 0 and then you should be able to sync with your new schema.

Thank you for your explanation, Jay and lan. That was very educational.

This is error logs.
]

Error:


Failed to convert MongoDB document to configured schema during initial sync

Source:


Error syncing MongoDB write

Logs:

[
  "Namespace: PrivateRealm.User",
  "Document ID: 5f7ed493b03d9dde55b49d4d",
  "Detailed Error: error encoding document during initial sync: document is missing required field(s): [exp level]"

Looking at your code, I believe this is because you’re using .modified in your realm.add call. Since the default value for int properties is 0, creating a user with 0s for exp and level will not set these properties. Since they’re not sent to the server, translating them to Atlas will also omit setting them, which this time results in the fields missing altogether. This is likely a bug in the Realm -> Atlas translation layer that we’ll need to address, but can you just confirm if this is the case? Setting the fields to non-zero values will be an easy check.

2 Likes

Thank you so much. I removed .modified and succeeded in synchronization.
Then I modified my code in order not to cause a below error.

Attempting to create an object of type 'User' with an existing primary key value 'jfwieo2t489fw2jfl'

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.