-
Notifications
You must be signed in to change notification settings - Fork 29.2k
Description
Is there an existing issue for this?
- I have searched the existing issues
- I have read the guide to filing a bug
Steps to reproduce
This issue / bug is being reported because I believe I have a duty of responsibility to report this issue, but don't have all the necessary / typical requirements to ensure this gets resolved.
What I do offer is a set of scenarios that were resolved by not using the SharedPreferences plugin, which leads me to assume there is something fundamentally wrong with the code or approach taken somewhere (or isn't documented in a way that avoids these issues from occurring).
The issue?
I have a complex / large Flutter application (~40K LOC) that is deployed into the wild on iOS, macOS, Android, Windows and Web. The application relies on SharePreferences for storing of key/value pairs relating to settings in the app. Things like username, tokens, theme settings, etc and so on.
On iOS, I've repeatedly had customers complain that the app forgets or is unable to retain details upon returning to the app after initial use - ie they start the app, make changes to the settings, and then subsequent activations of the app (ie from sleep or just restarting it) results in all those settings lost or not known.
Extensive debugging and logging hasn't been able to determine why, but it seems related to race conditions where the value is written and then later read (in other UI events) and the values are not kept/retained. It is behaving as if there are multiple threads that are updating/reading from different cached stores and are not being kept updated. ie the await used on the write doesn't stop another thread in dart UI that is reading the same key value which is not set (yet) in the persistent store.
Regardless, even when using reload() and other methods to keep a single instance of SharePreferences, the problems was not resolved. As a final solution, the internal "settings" class was migrated from using shared_preferences to get_storage and the problem went away - so the approach used by get_storage seems to work in a application design where shared_preferences did not. I'm unsure why, but obviously the plugin and/or code approach taken within shared_preferences has some limitations that are causing bugs/issues.
Expected results
That the use of shared_preferences works in all real world use cases where settings or key/value pairs are likely to be needed - ie within HTTP calls, multiple UI events, injected services etc. The test cases under which shared_preferences is currently evaluated are clearly not extensive enough to uncover issues and problems that might occur on some platforms (in this case iOS).
There are some issues reported of a similar nature, but are often closed or ignored by the Flutter team due to a lack of a simple example being provided. The problem is that it isn't easy to demonstrate concurrency issues with a persistent key/value store when the underlying cache might not yet be updated if another thread of execution is about to read for that same key value.
Actual results
A key value being written is not yet updated when read by another element of the event/thread etc.
Code sample
No code sample is possible.
Screenshots or Video
No response
Logs
No response
Flutter Doctor output
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.3, on macOS 12.6.5 21G531 darwin-x64, locale en-AU)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.78.2)
[✓] Connected device (2 available)
[✓] Network resources
• No issues found!