The Flutter shared_preferences package comes with a warning that says:
there is no guarantee that writes will be persisted to disk after returning
Because of that people often recommend using alternative solutions to local storage like Hive or SQFlite. (Aside from, of course, also backing up critical data on the cloud. But that’s a separate issue. Local storage might still useful regardless.)
But it’s unclear to me: what exactly does "no guarantee" means? And how is it different from other local storage solutions? In which situations would data stored with shared_preferences not be persisted? Which steps needs to happen to lose data?
Other discussions on Stack Overflow suggests that it could be not persisted because the user could manually delete the app’s cache. But if I understand correctly that would also be a problem with the alternatives like Hive or SQFlite, or did I misunderstand them? If not, then how do they store data differently to avoid that problem? Is the user manually deleting the data the only case where it wouldn’t persist? Or is there anything else I should be aware of?
2
Answers
The primary differences come from performance and use cases. HiveDB is generally used if you want a fast read and write time while sqflite is used if you want a local SQL implementation with support for transactions and versioning out of the box. shared_preference does provide a similar read time to hivedb but does not have the rest of the features. The risk of the user deleting the data does exist in all of them since even hivedb stores data in the user’s app directory. and hence if that is a major risk for your app then a cloud-based storage might be your answer.
As it says in the README, on some platforms the data is written asynchronously, so just because the future for a call to write data has completed doesn’t mean the data has actually been written yet. That means that if, for instance, the app is killed or the device loses power immediately after trying to set data–even if the future has returned–that write may be lost.
It’s possible to make a storage system where the future doesn’t return until the data has actually been persisted.
Usually the difference doesn’t actually matter; either way the data can be lost if the app is killed immediately. The difference is if something you do afterwards requires being in sync with that data. For example, if you are showing a confirmation message to users that data has been saved, or send something to a server that should only be sent once you know the data is written locally, you might need to know when it has actually been persisted.