Detect realm sync device connect/disconnect

I am using MongoDB Realm for an industrial IoT project. Each device in our network authenticates with its own realm API user and syncs event logs and sensor data to Atlas.

I need to be able to notify human users if the device disconnects from the internet. What is the best way to do that? I could realm.write a ping timestamp every minute or so on the device. And have a cloud function run every minute to check the age of that ping… but I’m wondering if there is a way that doesn’t require extra network requests? Can I set up a server-side trigger that gets run on realm user connection/disconnection events?

Thanks

4 Likes

@Shea_Dawson The way you described; sending a ping across sync every so often, is how we would recommend detecting online/offline from the server-side. In the future, we may look to add a “Presence” feature which you could hook into on the backend

YES!! This is something that is really needed to expand Realm’s functionality

I put a feature request in a while back (like 2017) and then again in 2020 for the Realm Object Server (before it became MongoDB Realm)

You should add this question as a feature request for MongoDB Realm.

Hey folks, if you are using a synced Realm, you are able to detect connected status (at least in the Swift SDK)–

let token = realm.session?.observe(\SyncSession.connectionState, options: .initial) { s, _ in
    if s.connectionState == .connected {
        // do stuff
    } else if s.connectionState == .disconnected {
        // do stuff
    }
}
1 Like

Whoaaa… Great news!

Is that an actual event that will fire upon connect/disconnect or a one shot deal where it has to be called upon use?

Yes, it will fire upon connect/disconnect.

It should be noted that the API Jason referred to is for local connection/disconnection behavior, in other words, the developer can tell the user whether they are online/offline.

For a “Presence” feature on the server-side which will tell you when a device is connected or offline we’d like to add this capability as we get the request from time to time, but I’d like to clarify that this feature is likely to just be a wrapper around the design pattern I described above. That’s because the only fool proof way to determine whether a network connection is active or not - IS to send a payload across the wire and get an acknowledgement back. There are so many reasons that a socket could appear active but, for example, has yet to timeout, or has massive packet loss, or the server has failed to garbage collect the stale connection, etc. Of course there are certain optimizations that only the product can do under the hood that wouldn’t be available to the user, and we will make those - but you should not think that leveraging this feature will save you from network traffic because it is likely to use the network to determine “presence”

-Ian

1 Like

The Sync Logs now have messages “Sync → Connection Start” and “Sync → Connection End”. This means that the detection of user’s connection state changes has already been implemented. It would be great to provide the ability to create a Trigger that fires on these events - this is an essential functionality for multi-user applications, and now this is our main problem when using Realm Sync in our application. Thanks.

3 Likes

@Ian_Ward The trigger on “Connection End” suggested by @orbi_inc would be very useful.

Context :
I am developing a mobile app that register user location when in use.
When they dont use it anymore i want to delete the location from the database.
But as they close the App, i dont have any way to delete this location from the database (at least IOS does not allow it - It just kills the app)
But being able to get the end of connection event as a trigger and the user linked to the session, i would be able to delete the location of this user when the application is closed/killed

Do you think that it could be implemented somehow?
Or do you know some workaround that can be easily implemented in the server side (atlas side)?

Thank you

Hi, we have 3 options for this kind of thing depending on your use case.

  1. Authentication Triggers (https://www.mongodb.com/docs/atlas/app-services/triggers/authentication-triggers/#std-label-authentication-event-operation-types)

    • You can define a trigger function to execute on a user being deleted (if that is something you can count on)
  2. Log Forwarder

  3. Sidecar Collection

    • We have some users that do this by maintaining a synced document per-user with a timestamp. You can then configure your application to update that document on some regular cadence.
    • You can use this value to determine when the last time a client connected. You can even setup a scheduled trigger to check for clients older than a certain time and go perform some action

Part of the reason we have not built this feature in directly is that we have found that everyone who asks this has a very specific need with a very specific design, and generally the general-solutions we think about building into the product would be useful possibly for you, but most likely not for the majority of people.

Best,
Tyler

I will (again) make a feature request on a User Presence system.

We feel this is a critical component missing from Realm - we put a feature request in about, oh, 8 years ago and at the time received a positive response. However, obviously it’s not yet a feature.

Something simple to start with would suffice - for example.

Online / Offline State Done The Right Way

So what do we do? We can solve the offline problem by utilizing a special feature in Firebase known as onDisconnect - a function that tells the Firebase server to do something when it notices a client isn’t connected anymore.

This is exactly what we want - we need to instruct the Firebase server to set the user’s presence boolean to false when it detects that the client went offline:

That quote is from Firebase in 2013 and can be found here

So again, a simple event that’s fired when a user is set to disconnected that can be monitored and responded to. Something similar to an object observer where the observer code is fired when an object property changes - in this case the server sets a user to ‘disconnected’ and then notifies the app.

Question for you @Jay, if we were to make a new Authentication Trigger type where it would run an App Services Function (as opposed to being defined within the client-side SDK) in response to a sync client connecting / disconnecting, would that fit your use case?

@Tyler_Kaye That sounds like a possible solution.

The big picture is there numerous use cases for knowing if the client has disconnected or not.

Imagine a Chat app where users can chat back and forth. What happens if a user you’re chatting with disconnects? You keep chatting when then with no response. Indicating the user has ‘gone offline’ for example, would improve that experience.

Or imagine a use case where users can open and edit documents but to prevent overwriting each others work, a document is marked as in use (preventing others from writing at the ‘same time’). If a user opens a document and then d/c’s - oops, the document is forever ‘locked’. Being able to run code to ‘unlock’ that document if a user d/c’s would improve that experience.

Or, in the original post - being able to handle d/c’s either on the client or server that doesn’t involve polling (how 1980’s) or excessive network requests.

1 Like

@Tyler_Kaye

I would like to know if there is any feature request already open for this and if there is any timeline or information about how long it would take to implement this new trigger?

Thank you
Best regards,
Cyril

@cyril_moreau

There is and was. I opened two feature requests about 6-7 years ago but those have disappeared with the Realm purchase and website change. There were a few discussions about it as well on the forums but I think those went away as well.

However, there is a standing request from 2020

There’s also a Kotlin example that both addresses handling a d/c on the client side (using SyncSession ConnectionState) as well as on the server side using a server function that scans the logs for connection changes.

I have not actually tried that solution but one of the issues is it can take up a minute to detect a d/c and the logs have to be continuously scanned via that function.

I am not an expert on server-side code but that example may be a copy/paste?

It would be great to have a more plug and play solution like Firebase has.