Matt Robertson
Matt Robertson

Reputation: 3165

SharedPreferences deleted after DataStore migration

I ran into this and the fix is simple but non-obvious, so I figured I would share.

I was migrating a single field from SharedPreferences to a Preferences DataStore and using the default SharedPreferencesMigration to do so. Every time the migration would run, my SharedPreferences file was deleted.

Upvotes: 1

Views: 1554

Answers (1)

Matt Robertson
Matt Robertson

Reputation: 3165

If you are migrating a single SharedPreferences preference to a Preferences DataStore (or multiple prefs but not all of them), you must provide a set of keys to the SharedPreferencesMigration. Not doing so will result in your SharedPreferences file being deleted.

This is the SharedPreferencesMigration's cleanUp() function that runs after the migration:

override suspend fun cleanUp() {
    val sharedPrefsEditor = sharedPrefs.edit()

    if (keySet == null) {
        sharedPrefsEditor.clear()
    } else {
        keySet.forEach { key ->
            sharedPrefsEditor.remove(key)
        }
    }

    if (!sharedPrefsEditor.commit()) {
        throw IOException("Unable to delete migrated keys from SharedPreferences.")
    }

    if (sharedPrefs.all.isEmpty() && context != null && name != null) {
        deleteSharedPreferences(context, name)
    }

    keySet?.clear()
}

Notice that the migration will remove every key that was migrated, or if no keys were provided, call clear() on the Editor, which removes all keys. Then if all keys are removed it will delete the file.

The fix for this is simply to provide a set of keys to the SharedPreferencesMigration, which it provides as an optional parameter.

SharedPreferencesMigration(
    context = context,
    sharedPreferencesName = "preferences file name"
    keysToMigrate = setOf("your key name")
)

Upvotes: 4

Related Questions