1

I am quite new to Realm and now I'm facing the issue, mentioned in the title. Basically, one of my Realms is a User class (this is different from Users that is created when new users log in) in Realm Cloud. The class has a userId property, which is set as its primary key. Now, I try to fetch users for a particular primary key with the following line:

let user = realm?.object(ofType: User.self, forPrimaryKey: "f677ca48b17bc7b90a886dd5d50148c1")

I do see that there is a user in the cloud with this primary key, but he is not always returned. I mean, say, if I run the same code 10 times, I will get the user only 4 times out of 10 (roughly). The above code is run from a method, which is always called when the controller is on screen. Also, there is no condition checking in the method for that part of code, so it is always called when the method is called.

I've also checked the realm property and it is not nil, so I don't quite understand why this happens.

The same happens when I try to get the current user by the line:

currentUser = realm?.object(ofType: User.self, forPrimaryKey: SyncUser.current?.identity)

The identity value is not nil (I print it before calling the code).

UPDATED

Here is how the User looks like:

 class User: Object {

 @objc dynamic var userId: String = ""
 @objc dynamic var name: String = ""

 override static func primaryKey() -> String? {
     return "userId"
   }
}

Maybe, I am missing something or that is a problem/bug on the cloud side, I don't know. If you've encountered such an issue and/or know what could cause it, I would greatly appreciate your help. Thanks in advance.

Tigran Iskandaryan
  • 1,371
  • 2
  • 14
  • 41

1 Answers1

0

This is caused because of the race condition that could pops up when you try to access a reference that is not on the main thread & being worked on by other thread .

therefore it will return nil each most of the time when you try to call it from the main thread because Realm had no chance to write or read from yet as you are accessing it directly .

What to do:

Make sure that your properties in the User object are marked with dynamic .

properties of your Object subclasses need to be declared with the dynamic modifier to allow Realm to override the getter and setter of the property.

Without this the Swift compiler will access the object's instance variable directly, which doesn't provide any opportunity for Realm to read or write data from the Realm file.

Also please read this answer .

Mohmmad S
  • 5,001
  • 4
  • 18
  • 50
  • Ok, I've updated the question, so check it, please. Also, as far as I understood from your answer, this happens because there is a race condition because the `realm` could be not on the main thread, so sometimes it doesn't manage to access it at the right time. Am I right, or missing something? – Tigran Iskandaryan Jan 08 '19 at 13:46
  • I've also tried to follow the suggestion in the question you've linked, but unfortunately I get the same result: a random appearance of users during iterations. – Tigran Iskandaryan Jan 08 '19 at 13:50
  • let realm = try! Realm() let specificPerson = realm.object can u try accessing it like this – Mohmmad S Jan 08 '19 at 14:02
  • I've tried but unfortunately it turns out I can't because I'm using query-based sync and for that I need to configure the Realm with synched user's configurations. – Tigran Iskandaryan Jan 08 '19 at 14:16