New User, unable to fetch, objects are in realm


#1

At the initialization of my app, I log all users out (getting the +current user error, not really a priority right now, but confusing none the less) and then login with the following:

let credentials = SyncCredentials.usernamePassword(
  username: user, password: pass)

SyncUser.logIn(with: credentials,
               server: server,
               timeout: 5.0) { [weak self] user, error in
                self?.serverDidRespond(user: user, error: error)
}

In my controller, I’m attempting to fetch a list of “Item” objects. I see them in Realm Studio, there are four of them. When I add to the realm, I can use the code below and retrieve the Item just written.

override func viewDidLoad() {
    super.viewDidLoad()
    let config = SyncUser.current?.configuration()
    realm = try! Realm(configuration: config!)
    
    theObjects = realm.objects(Item.self)
    print("Num: ", theObjects.count) // returns zero
}

I’ve also tried this:

    let syncServerURL = URL(string: "realms://<realm URL>")
    let user = SyncUser.current
    let config = user?.configuration(realmURL: syncServerURL, fullSynchronization: true)
    realm = try! Realm(configuration: config!)
    
    items = realm.objects(Item.self)
    print("Num: ", items.count)

items count always returns as zero. These are from the realm website.

What am I not understanding here? The four Items in the realm are all created by the same user. Thanks.


#2

For the first scenario, if you are using query-based sync you will need to subscribe to the Results object. This will begin the process of syncing data that satisfies the query to the device. You will also want to create a notification token to alert you once the sync process has completed or updated.

For the second scenario, where you have a full synchronization, you are also checking the .count before any data has synced. You can open the realm with .asyncOpen the first time you open the application, which will return the realm once the entire realm is downloaded.


#3

This is what I wrote in the other forum, with another user having the same issue. It appears to me the different context of Realm operation are being presented in the documents as a homogenous structure, when that’s not the case. Using the ‘local’ version is the same code as the ‘cloud’ version isn’t true. Regardless, I assume the code you are indicating (with exception of the second recommendation of asyncOpen) is below along with the output that doesn’t function.


I’ve been trying different combinations - what I’ve noticed is that if you put in the wrong URL, it doesn’t throw or indicate that it’s wrong. The only indication is positive - when you have the correct URL, you get the message in console:

Sync: Connection[1]: Connected to endpoint
So I thought, well maybe it’s a race condition, so I attached an observer to it, and break out all the options

do {
    self.realm = try Realm(configuration: config!)
    let results = self.realm.objects(Item.self)
    
    notificationToken = results.observe { [weak self] (changes) in
        switch changes {
        case .initial:
            print("Initial", changes)
            print("Initial Results Count", results.count)
            
        case .update(_, let deletions, let insertions, let modifications):
            print("Update", changes)
            print("Update Results Count", results.count)
            
         case .error(let error):
            print("Error")
       
        }
    }
    
}

If you notice below, when I add a new object the results var is updated. I suspect the documents are wrong and the observers are not returning object as expected in the initial state. I have only basic knowledge of observers. I would expect the results var at this point to contain what was requested, the objects. I’d expect changes to contain the array in the initial state, maybe this is a hot/cold observer thing that I’m not well versed enough to decode?

However - the update shows an insertion at [0], which is incorrect. I’m now up to eight items, so this should have been [7]. This makes me think it’s not even aware of the array on the server side. It’s also odd that the updates observer fires twice. Just to confirm, the new item is in the realm, confirmed via Realm Studio.

Initial initial(Results<Item> <0x7f907261dee0> (

))
Initial Results Count 0
2019-02-24 20:43:21.014103-0500 [73514:8117607] Sync: Connection[1]: Connected to endpoint 'x.x.x.x:443' (from 'x.x.x.x:55427')
2019-02-24 20:43:22.784047-0500 [73514:8117406] [MC] System group container for systemgroup.com.apple.configurationprofiles path is //data/Containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2019-02-24 20:43:22.784374-0500 [73514:8117406] [MC] Reading from private effective user settings.
Item "lame" added
Update update(Results<Item> <0x7f907261dee0> (
	[0] Item {
		id = CAAE0103-D4F8-4DB3-9FE3-5AC436CC6B33;
		owner = x;
		name = lame;
		timestamp = 2019-02-25 01:43:26 +0000;
	}
), deletions: [], insertions: [0], modifications: [])
Update Results Count 1
Update update(Results<Item> <0x7f907261dee0> (

), deletions: [0], insertions: [], modifications: [])
Update Results Count 0

#4

and if you look at the update - it’s inserting AND deleting the update. This really isn’t clear.


#5

Ok, here is with async open. I get the same results.

  let syncServerURL = URL(string: "realms://<URL FROM STUDIO>/default")
  let config = SyncUser.current?.configuration(realmURL: syncServerURL!, fullSynchronization: true)
 Realm.asyncOpen(configuration: config!) { realm, error in
        
        print("   ... opened.")
        if realm != nil {
            self.realm = realm
            // Realm successfully opened, with all remote data available
            DispatchQueue.main.async {
                // Set this as the configuration used for the default Realm
                Realm.Configuration.defaultConfiguration = config!
                print("Configuration: \(Realm.Configuration.defaultConfiguration)")
                print("Schema: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
                
            }
            self.loadItems()
            
        } else if error != nil {
            print("Unable to open Realm")
            print(error)
        } else {
            print("Something bad has happened!")
        }
    }

func loadItems() {
if (self.realm != nil) {
let results = self.realm.objects(Item.self)
print("Count: ", results.count)
}
}

Full Sync returns with:
Async Open
… opened.
Unable to open Realm
Optional(Error Domain=io.realm.sync Code=4 “Operation canceled” UserInfo= .
{NSLocalizedDescription=Operation canceled, statusCode=89})

This is mentioned a lot in SO, but the solution is usually Full Sync, which I’m in.