What is the purpose of Subscriptions

Looking for a one-line explanation of what Subscriptions are for. From the docs

You can manually add, update, and remove subscriptions (results .subscribe) to determine which data syncs to the client device.

and the example

let results = try await realm.objects(Task.self)
    .where { $0.progressMinutes >= 60 }.subscribe()

this query indicates we want to query realm for all Task objects where progressMinutes >= 60

however, the expected results of this code would be identical

let results = try await realm.objects(Task.self)
    .where { $0.progressMinutes >= 60 } //no .subscribe

We still expect all Tasks where progressMinutes >= 60.

What is the need/purpose of .subscrbe in the first example? Either way, the expected result is the same. Why does .subscribe() need to be implicitly specified?

. subscribe tells the server which data to send the client. The local results are the same, but if you don’t subscribe, the server will not send you any data.

@nirinchev Thank you.

For clarity, does that mean omitting .subscribe will only query the local Realm (possible stale data) and the data in that Realm will not be sync’d?

Does that also mean this code does not start a sync of the object types listed?

var flexSyncConfig = user.flexibleSyncConfiguration()
flexSyncConfig.objectTypes = [Task.self, Team.self]

Or does .subscribe replace that code since the object can be defined in the query?


Well, hmmm. Our testing shows that with NO subscription, our app still receives events and data. It’s very confusing. Here’s our code that opens flex Realm. Note that the subscription section is commented out. There is NO other code in the app that does anything with opening the Realm.

    func openFlexibleSyncRealm() async throws -> Realm? {
        do {
            guard let user = gTodoApp.currentUser else {
                return nil

//            var config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
//                subs.append(
//                    QuerySubscription<ToDo> {
//                        $0.complete == false
//                    }
//                )
//            })
            var config = user.flexibleSyncConfiguration()
            config.objectTypes = [ToDo.self]

            let realm = try await Realm(configuration: config, downloadBeforeOpen: .always)
            return realm
        } catch {
            print("Error opening realm: \(error.localizedDescription)")

        return nil

When this code is run, if I open the Realm Console and manually add data, it’s immediately sent and sync’d with the client - and vice-versa. When a ToDo is added on the client it’s immediately pushed to Atlas.

So in spite of having no subscriptions, the app still receives data.

What is going on? .subscribe is not used anywhere in the app.

Subscriptions are persisted in the Realm and will be used between app restarts. If you had setup subscriptions previously, it’s possible that they are responsible for the data synchronization you’re observing. You can check what subscriptions are already setup for a Realm by accessing the realm.subscriptions property.

and that’s the answer. Once this was run

subscriptions.removeAll(ofType: Team.self)

It stopped receiving events .

Looking forward to this feature becoming non-preview and the documentation being updated!