On this page
A client reset error is a scenario where a client realm cannot sync data with the application backend. Clients in this state may continue to run and save data locally but cannot send or receive sync changesets until they perform a client reset.
The client reset process loses any unsynced changes even if they were successfully saved locally. To avoid data loss, you must manually back up and restore any unsynced changes when you handle a client reset.
Client reset scenarios occur when the server's history is incompatible with the client's history. The most common causes of client resets are:
- App Services server crashes: A server may restore from a backup that has an earlier version. A client reset for this scenario would reset the client to the earlier version and lose any changes that were saved on the client but not yet synced with the server.
- Disabling and re-enabling sync: Turning Sync off and then on again in the Atlas App Services UI causes all clients to require a client reset.
- Client/Backend schema mismatch: If a client application attempts to synchronize with the backend while using a Realm Object schema that does not exist in the backend, that client must perform a client reset. This only applies in one direction: if the backend schema contains an Realm Object class not used in a client, that client does not need to client reset.
- Client maximum offline time: When a client has not synchronized with the backend in more than client maximum offline time days, that client can no longer synchronize unsynced local changes with the backend. The client must discard all local changes since the last sync and download the current status of the realm from the backend.
- Breaking schema changes: A breaking or destructive change, like changing a property type or a primary key, requires you to terminate and re-enable Sync. This creates a new synced realm file with a version unrelated to the client's file. Because this scenario requires a new realm file, you can only handle client resets caused by breaking changes using the manually recover unsynced changes strategy.
- Upgrading from a Shared to Dedicated cluster: When you upgrade from a shared to a dedicated cluster, you must terminate Sync on the old cluster. After you upgrade, you can re-enable Sync. Turning Sync off and then on again causes all clients to require a client reset.
Session role changes: When using Flexible Sync, changes to a user's Flexible Sync session role result in a client reset. The following scenarios all result in a client reset:
NoteBreaking Schema Changes Require an App Schema Update
- server-side modifications to the session role
- changes to the value of any expansions in the "apply when", read, or write expressions
- changes that qualify the user for a different session role
After a breaking schema change:
- All clients must perform a client reset.
- You must update client models affected by the breaking schema change.
The SDKs automatically detect the need for client resets. You can handle client resets in your application using one of the available client reset strategies:
You can only handle a client reset triggered by breaking changes using the manually recover unsynced changes strategy.
This client reset strategy permanently deletes any changes made locally that have not yet synchronized to the backend. Do not use this client reset strategy if your application needs to preserve unsynced changes.
The discard unsynced changes strategy automatically handles client reset events without the need for app-specific logic. During a client reset that uses this strategy, the client:
- Downloads a fresh copy of the realm from the backend.
- Performs a diff to figure out the set of steps required to bring the original (local) copy of the realm to the same state as the fresh copy of the backend.
Applies that set of steps to transform the local realm into a state where it can sync with the backend. This includes:
- deleting all local changes that haven't yet synced to the backend
- any inserts, updates, and deletes that haven't yet synced to the client
- Discards the fresh copy. The app continues to use the original copy of the realm with the diff applied.
The "discard unsynced changes" strategy has several advantages compared to manual recovery:
- Your application can perform a client reset without writing any custom logic, other than specifying this strategy. You don't have to manually initiate the client reset or interact with the error object at all.
- Your application can perform this client reset without closing any realms, disconnecting from the backend app, or manual restarts. This means you don't have to write any logic to handle these situations.
- Application users receive notifications for changes as the local realm updates to match the state of the backend realm.
There is one major disadvantage to this strategy, however:
- There is no way to recover changes that have not yet synced to the backend at the time of the client reset. When this strategy uses a diff to bring the local realm to the same state as the backend, unsynced changes are permanently deleted and cannot ever be recovered.
You can use this strategy to resolve a client reset caused by anything except a breaking schema change.
This strategy works just like the deprecated "Client Reset Handler" method of performing client resets. Applications that use deprecated client reset handling can switch directly to the "manually recover unsynced changes" strategy with no logic changes.
The manually recover unsynced changes client reset strategy gives the app developer complete control over recovery from client reset errors. During a client reset that uses this strategy, the client:
- Makes a backup of the original (local) copy of the realm. Before making the backup, you must close all instances of the realm. If your application architecture makes this difficult, you can restart the app and handle the client reset on reconnect.
- Downloads a fresh copy of the realm from the backend. This fresh copy replaces the original local realm.
- Provides a reference to the local realm backup and the fresh copy of the realm.
With the local realm backup and the fresh copy in hand, you can triage and save local data by copying it from the local realm backup to the fresh copy of the realm. Recovering unsynced changes is highly dependent on your schema and application logic, so you may need to supplement your schema with "last modified" timestamps for best results.
Manual recovery has one major advantage compared to discarding unsynced changes:
- You can recover local changes that haven't yet synced to the backend.
There are several disadvantage to this strategy, however:
- You must write custom logic to initiate the client reset.
- You must close all realms before performing the client reset.
- Application users never receive notifications for new changes that synced from the backend during the client reset.
- You must either restart the application or write custom logic to re-initialize the backend app connection after performing the client reset.
For more information on performing a client reset, check out the client reset examples for your SDK: