Handling Conflicts & Synchronization
Cloud Services in Essential Kit let you save and retrieve simple key-value pairs that automatically sync between local and cloud storage. It’s designed to be simple, fast, and reliable – with built-in support for detecting conflicts during synchronization.
Let’s explore how it works using an example.
🎮 Use Case: Saving Player Settings
Imagine you’re working on a game where the player can configure their settings – like the selected language, sound volume, or preferred difficulty. You want to store these preferences in the cloud, so that if the player installs the game on another device, their settings come along.
Step 1: Save Settings to Cloud
Let’s assume the player updates their preferred language setting.
CloudServices.SetString("player.language", "en");
This will immediately update the local cache with the value "en"
for the key player.language
. At this point, the value is still only available locally – it has not yet been pushed to the cloud.
✅ Tip: All
Set*
methods update local cache immediately.
Step 2: Synchronize with Cloud
When you want to push or pull the latest data to/from the cloud, call:
csharpCopyEditCloudServices.Synchronize();
This will:
Fetch the latest copy of cloud data.
Compare the local and cloud versions.
Detect if any keys have changed in both locations since last sync.
If a conflict is detected (i.e., both local and cloud versions were modified), Essential Kit overwrites the local value with the cloud copy and triggers an event CloudServices.OnSavedDataChange
Step 3: Handle Conflict in OnSavedDataChange
OnSavedDataChange
You can listen for this event and inspect which keys had conflicting values:
void OnSavedDataChange(string[] changedKeys)
{
//📌 Important: CloudServices.GetString(key) here now returns the cloud value, since the local cache has already been updated.
for (int i = 0; i < changedKeys.Length; i++)
{
string key = changedKeys[i];
string cloudValue;
string localCacheValue;
// Retrieve both cloud and local values before the overwrite
CloudServicesUtility.TryGetCloudAndLocalCacheValues(key, out cloudValue, out localCacheValue, "default");
Debug.LogFormat("[{0}] Key: {1}\n [Cloud Value]: {2}\n [Local Cache Value before overwrite]: {3}", i, key, cloudValue, localCacheValue);
// Decide what to do: Keep cloud version or restore local
if (ShouldKeepLocalValue(key, localCacheValue, cloudValue))
{
// Restore the local value
CloudServices.SetString(key, localCacheValue);
//Calling CloudServices.GetString here will return localCacheValue as we updated with SetString
}
}
}
Step 4: Finalize with SynchronizeComplete
SynchronizeComplete
After the sync is completed (and any conflict resolution is done), the SynchronizeComplete
event fires:
CloudServices.OnSynchronizeComplete += () =>
{
Debug.Log("Cloud sync complete.");
};
If you restored a value during conflict resolution using SetString
, the updated value will be pushed to the cloud on the next sync cycle – either manually triggered or automatically (e.g., app going to background).
⚡ Quick Recap
SetString("key", value)
Immediately updates local cache
Synchronize()
Syncs data, resolves conflicts, and fires events
OnSavedDataChange
Fires after a conflict, providing keys that were overwritten by cloud
TryGetCloudAndLocalCacheValues
Lets you inspect both the cloud and previous local values
SetString(...)
inside event
Lets you restore the local value if cloud data is not what you want
OnSynchronizeComplete
Fires after sync and conflict resolution is done
Example Conflict Flow
Let’s say:
Player changes
"player.language"
to"en"
locally.On another device, the same key is changed to
"fr"
.Player syncs both devices.
During sync, the cloud value "fr"
is fetched and overwrites the local "en"
, triggering OnSavedDataChange
. Now you can use the utility function CloudServicesUtility.TryGetCloudAndLocalCacheValues
to retrieve both the cloud value ("fr"
) and the old local value ("en"
), allowing you to decide whether to keep the cloud version or restore your original local data.
Last updated
Was this helpful?