Creating a SnapshotService persisting Objects using Shared Preferences in Flutter
Persisting NoSQL Data in your Flutter Application
Flutter is probably one of the newest open source cross-plattform frameworks published by Google. More and more people are starting to develop applications using the Flutter framework.
For a private project I started to use Flutter as well. This project utilizes the Realtime Database Firebase which is from Google as well. As Firebase returns a DataSnapshot which can be easily converted into JSON, I started thinking about how to persist my data in a good way in a smartphone application. Therefore Flutter offers the Plugin: SharedPreferences.
The Functionality of SharedPreferences:
SharedPreferences works as an Key-Value Store on the Phone. It saves the data type Map<String, dynamic>
. It should only be used for simple data!
As Flutter is a cross-plattform framework the plugin wraps the SharedPreference into NSUserDefaults on iOS and into SharedPreferences on Android.
The Maximum Size which can be stored to your Shared Preference is: 2147483647 or to say it in a developer way: Integer.MAX_VALUE
.
I assume that if you came across this article you already have at least a basic project in Flutter.
Why this article?
After one day of using SharedPreferences I was facing the issue that, as it seems, not many available examples on the internet store full JSONs in there. Often only one String or an Integer Value were stored to SharedPreferences.
How to include SharedPreferences into your Project
Add Dependencies to your pubspec.yaml file
First of all we will add all necessary dependencies. Therefore go to your pubspec.yaml file in your project tree:
Check if the versions are up to date on PubDev or just run flutter pub upgrade
in your terminal.
Check your installation by running the command:
flutter pub run build_runner build
If this command runs without any error then everything went well! Later on this command will generate files including fromJSON()
and toJSON()
Methods for the class that you wanna store to the SharedPreferences.
Class Creation
The next step is to create a class which you want to store in the shared preferences of your phone. In my case I want to create a grocery shopping list persisiting my grocerys on the phone, which prevents me from reloading the data on every page or passing the data from class to class.
First create your basic class, including all your parameters for the class:
For making your class serializable the annotation @JsonSerializable
is used therefore you also have to import the 'json_annotation'
— library. For generating the toJSON()
and fromJSON()
Methods for your class you have to add the following line above the annotation.
part 'grocery_list_item.g.dart';
Adding it for the first time, the line above will be marked as an error. The error will be gone after running the generation command from the serializable package. Before running that command we will add some more code to the class file.
As a last step in your class file add a factory using fromJSON()
under your constructor and also the Map<String, dynamic> toJSON()
parsing your class into a JSON.
As an information if you are using factory for the first time:
Using a factory constructor is quite similar to a static method with the differences that it is not possible to use a initializer list: (val: super())
and it can only return an instance of the current class or one of its subclasses.
After this steps run:
flutter pub run build_runner build --delete-conflicting-outputs
You don’t have to add:
--delete-conflicting-outputs
but if you change something on your classes this parameter prevents you from running in errors which is always slowing down development speed and causes resignation ;) trust me!
By running the command above your:
part 'grocery_list_item.g.dart';
file will be created.
From the page where you call your backend service (whatever it is(Firebase, REST, GraphQL)) after getting your response and getting it into correct shape of your object call the SnapshotService with:
Getting data from shared preferences:
Why this approach?
Using the JSON serializable package for the toJSON()
and fromJSON()
Methods it prevents you from running into parsing errors when moving your data back and forth. It makes it also easy to include other objects into your Object.
You could make an outer class having your GroceryListItem in it e.g.:
with using then the generated Methods toJSON()
and fromJSON()
its easy to store your object to Shared Preferences even if it has a more complex Object in it than an Integer or a String.
Thanks for reading if you have any question or feedback let me know.