Check when syncing is done

cloud
ros
platform

#1

Simple task: check if a user with an email exists.

In an app with a Rest api server, this could be function that returns true/false, no network or error.

To do this in realm cloud, from what I have read, I have to deal with a “one time” subscription (please correct me if I’m wrong).

I’m trying the following (Swift):

query = realm.objects(User.self).filter("email = '\(email)'")
subscription = query.subscribe()
token = subscription.observe(\.state) { [weak self] state in
            switch state {
            case .complete:
                if self.query.count == 0 {
                    completion("Doesn't exist, you can sign up")
                } else {
                    completion("Exists, you can't use this email")
                }
                self.subscription?.unsubscribe()
            case .error:
                completion("Error")
                self.subscription?.unsubscribe()
            default: break
            }
        }
    }

I found 2 issues with this:

  1. If I don’t have network connection, the state stays as “.pending” until connection resumes, but I want this call to complete asap. If I don’t have connection, I want to complete with a “no connection” error asap, and if it fails for another reason, just complete with an unknown error. Is there a realm-way to do this?

  2. If I call this function once and succeeds, but I don’t unsubscribe, and then I put airplane mode and call this function again, I receive a “.complete”, returning the same info as before… that can be misleading as data could have changed in the server. A flag to know if everything is up to date would be useful for this maybe, I tried with addProgressNotification, but it’s being called when transfers complete, but not when there are connection issues.

  3. Bonus question: I’m in the need of a flag to know, in a given moment, if everything is “up to date” with the server, or “is syncing”, or “no network connection” (or “sync is pending”), to show to the user in a label. Is there an easy way do this? This may also help for question 2.


#2

@chris32786 It looks like you are trying to use query-based sync as a drop-in replacement for a GET request with a query but realm sync is different because it persists data to disk. Query-based sync is just a method for populating this local cache of data in realm. Unless it’s just way too much data, I would just subscribe to all of the users and do local queries perhaps via a full sync global or common realm. If it is way too much data, probably contort the data model to make it so that the relevant subset is a reasonable size. Take a look at our different realms writeup here - https://docs.realm.io/sync/using-synced-realms/designing-an-architecture-with-multiple-realms

the bonus question is actually a lot easier: observing the connectionState property of the session plus a download progress notification will tell them if it’s disconnected, currently updating, or up-to-date


#3

Thanks @ianward.

I’m using a query based sync realm. I don’t like to sync all users, I find it a bad practice to sync all users of the app into the client, it’s low performant and not very secure. And I don’t see a way to subset users for this case, is just a search by email in ALL users.

The approach I’m presenting has more sense to me, to query and then just dispose the subscription, but idk. I will try to figure out to make it work correctly, but I find this disappointing, it’s just a basic task… :worried:


#4

Same pain here.
It’s completely unclear how to use Realm properly. Query-based sync sounds like the best option, but I’m personally struggle with it. And yes, drop-in for GET request seems to be the only sane way of updating specific record.
Let’s say I’m building real-time application (similar to what you guys had in example for drawing application) - there’s no way we can use load everything and once stay happy - records are constantly changing and we need to show most relevant info