Debug School

rakesh kumar
rakesh kumar

Posted on

Flutter | How to use Secure Storage Instead of Shared Preferences.

Secure Storage
shared-preferences-or-flutter-secure-storage
flutter-advanced-secure-storage
what-is-flutter-secure-storage-exactly-and-how-it-works
how-to-implement-a-process-that-uses-flutter-secure-storage-package-to-read-and
secure-storage-in-flutter

Shared Preferences
Shared Preference uses a Key-Value approach to store data. It uses “NSUserDefaults” for iOS and “SharedPreferences” for Android.

Following Datatypes are supported,

int

double

bool

String

List<String>
Enter fullscreen mode Exit fullscreen mode

Implementation
Install package

shared_preferences: //latest
Next, Create the instance as,

SharedPreferences sp = await SharedPreferences.getInstance();
Enter fullscreen mode Exit fullscreen mode

Writing the data
1- Storing & Retrieving (int) value

//Storing

sp.setInt("myKey", 0);
Enter fullscreen mode Exit fullscreen mode

//Retrieve

sp.getInt("myKey");
Enter fullscreen mode Exit fullscreen mode

While retrieving if the value is null you could pass a default value, there is a way to handle it.

sp.getInt("myKey") ?? 0;
Enter fullscreen mode Exit fullscreen mode

2- Storing & Retrieving (double) value

//Storing

sp.setDouble("myKey", 56.9);
Enter fullscreen mode Exit fullscreen mode

//Retrieve

sp.getDouble("myKey");
Enter fullscreen mode Exit fullscreen mode

To handle null value use this,

sp.getDouble("myKey") ?? 1.0;
Enter fullscreen mode Exit fullscreen mode

3- Storing & Retrieving (bool) value

//Storing

sp.setBool("is_avl", true);
Enter fullscreen mode Exit fullscreen mode

//Retrieve

sp.getBool("is_avl");
Enter fullscreen mode Exit fullscreen mode

To handle null value use this,

sp.getBool("is_avl") ?? false;
Enter fullscreen mode Exit fullscreen mode

4- Storing & Retrieving (String) value

//Storing

sp.setString("file_path", "path_url");
Enter fullscreen mode Exit fullscreen mode

//Retrieve

sp.getString("file_path");
Enter fullscreen mode Exit fullscreen mode

To handle null value use this,

sp.getString("file_path") ?? "path_url";
Enter fullscreen mode Exit fullscreen mode

5- Storing & Retrieving (List) value

//Storing

sp.setStringList("countries", <String>["PK","IN","AU"]);
Enter fullscreen mode Exit fullscreen mode

//Retrieve

sp.getStringList("countries");
Enter fullscreen mode Exit fullscreen mode

To handle null values use this,

sp.getStringList("countries") ?? <String>["PK","AU"];
Enter fullscreen mode Exit fullscreen mode

Removing Keys
If want to remove a specific one,

await sp.remove("your_key");
Enter fullscreen mode Exit fullscreen mode

Otherwise,

await sp.clear();
Enter fullscreen mode Exit fullscreen mode

Best use
Use for Storing tokens, authentication ID, etc.

Flutter Secure Storage
This package is used to store data in Secure Storage and it is wrapped with encryptions, separate for Android & iOS.

For iOS, Key Chain services are used for storing small chunks, whereas AES for Android and AES itself is encrypted with RSA. Secondly, as of version 5.0, we can make now use of “enableSharedPreferences” which claims to secure reading and writing data in an extended manner (for Android).

Implementation
Install package

flutter_secure_storage: //latest
Enter fullscreen mode Exit fullscreen mode

Next, Create the instance as,

FlutterSecureStorage storage = FlutterSecureStorage();
Enter fullscreen mode Exit fullscreen mode

Writing the data

Future setUsername(String value) async {
  await storage.write(key: "username", value: value);
}
Enter fullscreen mode Exit fullscreen mode

Reading the data

Future getUsername(String key) async {
  return await storage.read(key: key) ?? "N/A";
}
Enter fullscreen mode Exit fullscreen mode

For Further Securing (for Android only)

Create an instance of AndroidOptions,

AndroidOptions _secureOption() => AndroidOptions(
     encryptedSharedPreferences: true,
   );
Enter fullscreen mode Exit fullscreen mode

And pass this when you write new data,

Future setUsername(String value) async {
  await storage.write(key: "username", value: value, aOptions: _secureOption());
}
Enter fullscreen mode Exit fullscreen mode

FlutterSecureStorage localStorage = FlutterSecureStorage();
Future setString(String value) async =>
await localStorage.write(key: "token", value: json.encode(data['token']));
await localStorage.write(key: "user", value: json.encode(data['user']));
await localStorage.write(key: "userid", value: json.encode(data['userid']));
await localStorage.write(key: "useremail", value: json.encode(data['useremail']));
await localStorage.write(key: "useraddress", value: json.encode(data['useraddress']));
await localStorage.write(key: "username", value: json.encode(data['username']));
await localStorage.write(key: "userphone", value: json.encode(data['userphone']));

Removing Keys
If want to remove a specific one,

await storage.delete(key: "key");
Enter fullscreen mode Exit fullscreen mode

Otherwise,

await storage.deleteAll();
Enter fullscreen mode Exit fullscreen mode

First of all, we will create a class and define both phone settings and write and read methods under this class.

Image description

We have enabled encryption for Android. For iOS, the data in the key element is unlocked once by the user. Until it opens, we made it inaccessible after a reboot. And we assigned these properties to FlutterSecureStorage.

Now let’s define the write methods;

Image description

As you can see, all methods take a key and a value parameter. Only the type of these values changes. And because we cannot predict how long these transactions will take, we call them asynchronous transactions. So, these will be somewhere in the future.

You might be wondering how I can keep a List in local memory, it’s pretty simple. But there are a few things to note.

Image description

We should take a look at the _setList method. This List can be of any type. For example; String, int, double vs. That’s why we use Generic Type (T). Then we want a key parameter and we get a value of type T. This value is currently a List. But our value must be String. So, we transform this list thanks to the json.encode() method.
Thus, the _setList method helps us with other methods as well.

That’s it for writes to phone memory! :)
Next are the read operations;

Image description
The first read method is about reading the value of all keys. Set after Future means: A collection of objects in which each object can occur only once.
That is, for each object of the element type, the object is either considered to be in the set, or to not be in the set.
By the way, after String ? the reason for using it may be that a value has not been written before, and therefore value can be null.
After making this short definition, we want to read all the data with the readAll() method. And of course by typing keys we say I want the keys. Then, thanks to the toSet() method, we get the values ​​corresponding to the keys.
However, I want to tell you that toSet works exactly as follows;
final planets = {1: ‘Mercury’, 2: ‘Venus’, 3: ‘Mars’};
final valueSet = planets.values.toSet();
// {Mercury, Venus, Mars}

Our other method is getString(). It asks us for a parameter to learn which key to listen to. Where we’re going to use it, we can write it like this: getString(“userId”). This tells us the value of the userId.

We read the bool and num values as follows;

Image description

First of all, we create an object and read and assign the parameter taken from the outside to this object. Then we create a control structure with if else. I want to explain step by step.
If the value we read is null, the method returns null,
true if the value we read is true. You know the rest :)

Here’s how to delete and delete all:

Image description

For the delete operation, we need the key that we want to delete.

I know the article is getting a little long. But you can believe me that knowing flutter_secure_storage will give you another dimension. Now that you’ve read this far, you deserve a few tricks!

Image description

Most of the resources I’ve seen regarding local storage have consisted of just closing and reopening the application and re-displaying a text (or anything like that) typed into the TextFormField. This is frustrating! Because you will not use it in business life. In business, you will often use local storage for userId, token, etc.

The above enum and extension are written according to clean code guidelines. It wouldn’t be a problem if we didn’t write them, but by typing it was much better.

Returns an expression for each enum. We will also use this in service operations. To give you an example, I have defined a method just below them. I think you understand better now.

Now we come to the most crucial point. How will you use it at an advanced level in services? That’s it;

Image description

Top comments (0)