Multiple sharedpreference for Multiple users, is it necessary? - flutter

i stored a list of data in sharedpreference which is only viewable by a particular user, however when i try to login another account i am still able to view the data.
Is it due to local development environment so that even if different user logged in we will still read the same sharedpreference file? Can i assume once the app go into production, the issue will be gone since the users should be using different machine?
If not, how can i achieve multiple sharedpreference for multiple user?
Thanks!

It's most likely due to the way that you are storing the data. Shared preferences depend on keys Strings. If you are storing different users but using the same keyword for all of them, i.e user, then it won't be unique.
Specify a unique key for every user, and easiest thing to do is use their email. When you store that data in your shared preferences, use this unique key for every user. This way you don't have data overlapping.

Store json data to shared preference as string .
then you can store unique key for each individual user and value for them .
Here is the example of storing json as string : (Note this Example is for Single object , for Multiple user use Array List with multiple object on it )
SharedPreferences shared_User = await SharedPreferences.getInstance();
Map decode_options = jsonDecode(jsonString);
String user = jsonEncode(User.fromJson(decode_options));
shared_User.setString('user', user);
SharedPreferences shared_User = await SharedPreferences.getInstance();
Map userMap = jsonDecode(shared_User.getString('user'));
var user = User.fromJson(userMap);
class User {
final String name;
final String age;
User({this.name, this.age});
factory User.fromJson(Map<String, dynamic> parsedJson) {
return new User(
name: parsedJson['name'] ?? "",
age: parsedJson['age'] ?? "");
}
Map<String, dynamic> toJson() {
return {
"name": this.name,
"age": this.age
};
}
}

Related

Store data model into Flutter Secure Storage

How do we store model data to flutter secure storage... or does it supports it?
I have a model like this... I load data from my API to this model... once I have data, I wanted to save it to the flutter secure storage and vice versa(load entire data to model from flutter secure storage)...
class MyUserModel {
MyUserModel({
this.authKey,
this.city,
this.contact,
this.email,
this.isContact,
this.userId,
});
String authKey;
String city;
String contact;
dynamic email;
bool isContact;
int userId;
}
Of course, I know we can read and write data like below... I am just checking if there is a way where we can directly write it from the model...
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
// Create storage
final storage = new FlutterSecureStorage();
// Read value
String value = await storage.read(key: key);
// Write value
await storage.write(key: key, value: value);
I saw hive supports this feature out of the box but I realized that it takes little time (2-3 sec) for initialization also Author is working on an alternative to hive due to two major blocks... the new database called Isar which clears all roadblock but it is still in development...
if it is possible then please share the sample code...
to save the object:
convert your object to map with toMap() method
serialize your map to string with serialize(...) method
save the string into secure storage
for restoring your object:
deserialize secure storage string to a map with deserialize(...) method
use fromJson() method to get your object
by that, you will serialize your data into a string and save and retrieve them.
class MyUserModel {
String authKey;
String city;
String contact;
dynamic email;
bool isContact;
int userId;
MyUserModel({
required this.authKey,
required this.city,
required this.contact,
required this.email,
required this.isContact,
required this.userId,
});
factory MyUserModel.fromJson(Map<String, dynamic> jsonData) =>
MyUserModel(
authKey: jsonData['auth_key'],
city: jsonData['city'],
contact: jsonData['contact'],
email: jsonData['email'],
isContact: jsonData['is_contact'] == '1',
userId: jsonData['user_id'],
);
}
static Map<String, dynamic> toMap(MyUserModel model) =>
<String, dynamic> {
'auth_key': model.authKey,
'city': model.city,
'contact': model.contact,
'email': model.email,
'is_contact': model.isContact ? '1' : '0',
'user_id': model.userId,
};
static String serialize(MyUserModel model) =>
json.encode(MyUserModel.toMap(model));
static MyUserModel deserialize(String json) =>
MyUserModel.fromJson(jsonDecode(json));
}
Usage:
final FlutterSecureStorage storage = FlutterSecureStorage();
await storage.write(key: key, value: MyUserModel.serialize(model));
MyUserModel model = MyUserModel.deserialize(await storage.read(key: key));
You can do this by encoding your Model into json saving it in Secure Storage and then decode the json and get the model back.
// Saving model into Storage
static Future<void> setMyUserModel(MyUserModel user) async {
await const FlutterSecureStorage().write(
key: 'user', value: user.toRawJson());
}
// Getting model from storage
static Future<MyUserModel> getMyUserModel() async {
return MyUserModel.fromRawJson(
await const FlutterSecureStorage().read(key: 'user') ??
'{}');
}
And of course you need to implement fromRawJson() and toRawJson() inside your model.
Sorry for the late reply :P.
To do this, encode your model into JSON and store it in secure storage. Later, decode the JSON to retrieve the model.
final storage = FlutterSecureStorage();
static const String modelData = "modelData";
// Saving model into Storage
static Future<void> setModel(user) async {
final jsonDataEncoded = jsonEncode(jsonData);
await storage.write(key: modelData , value: jsonDataEncoded);
}
//call this when you want to store your data to secured storage
ClassName.setModel(decodedResponse);//decode your json and send it here
//to read data from the local storage || secured storage
static Future<MyModel> getDataFromLocalStorage() async {
final jsonModel = await storage.read(key: modelData);
final jsonData = jsonDecode(jsonModel.toString());
final items = List.from(jsonData);
dataList = items.map((e) => MyModel.fromJson(e)).toList();
return dataList;
}

Flutter- understanding models

i just wanted to ask since this thing got me confused, i am still beginner with OOP i started it with Java and now working with it in flutter, so basically when i use a model in flutter, am i using it to fetch data from an api or a web server, am i right? let's say it's like select .. from .. in SQL, is that right? for example here i have this model of location
import './location_fact.dart';
class Location {
final String name;
final String url;
final List<LocationFact> facts;
Location({this.name, this.url, this.facts});
}
so basically in final name and final url i am specifying which data to get from the api or the web server ( in the example i am just giving fake data which just data i am giving it manually without a third party api or web server ) so when i use these i am just like using select name, url from "apĂ®" ? is that the deal here? and when i am using the Location({this.name, this.url, this.facts}) am i specifying which data this model will take as a parameter ? and when i am using final am i like referring to the data that it won't be fetched again once it's fetched? and when i am using final list <LocationFact> facts; am i specifying that this data is going to take the facts only from the list or what? i know this is overwhelming but i am really beginner with dart and flutter generally, i appreciate anyone's help and thank you.
I think you're reading too much magic into the word "model". In the original "MVC" triad, there are Models (places to stash data), Views (basically Widgets in Flutter), and Controllers (generally buried in Widgets in Flutter, but can be and should be pulled out to testable and reusable logic). Does that help?
First of all if you fetching data from API it will return data in json format as json Object or json List after fetching data from API you can use json data or you can convert json Object to Plain Dart Object
To convert json data to Plain Dart Object you have to specify your model class.
Here is an example to design a model class
class Location {
String name;
String url;
List<Facts> facts;
Location({this.name, this.url, this.facts});
Location.fromJson(Map<String, dynamic> json) {
name = json['name'];
url = json['url'];
if (json['facts'] != null) {
facts = new List<Facts>();
json['facts'].forEach((v) {
facts.add(new Facts.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['url'] = this.url;
if (this.facts != null) {
data['facts'] = this.facts.map((v) => v.toJson()).toList();
}
return data;
}
}
class Facts {
String locationFact;
Facts({this.locationFact});
Facts.fromJson(Map<String, dynamic> json) {
locationFact = json['locationFact'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['locationFact'] = this.locationFact;
return data;
}
}
Here Location.fromJson() is an factory method to convert your json object to Plain Dart Object
For reference you should take a tour into the Official Documentation
Fetch Data From Network Flutter Documentation

how to save list<object> in flutter

List<Data> datas = [];
Future<List<Data>> getData() async {
final response =
await http.get('https://iptv-org.github.io/iptv/index.country.m3u');
final m3u = await M3uParser.parse(response.body);
for (final entry in m3u) {
Data data = Data(entry.title, entry.attributes['tvg-logo'], entry.link,
entry.attributes['tvg-language'], 'false');
datas.add(data);
}
return datas;
}
class Data {
String title;
String logo;
String url;
String language;
String isFavorite = 'false';
Data(this.title, this.logo, this.url, this.language, this.isFavorite);
}
Everytime I get the data from the url, then how I gonna save the list of Data object? Can I save the data using sharedPref?
for complicated data its recommended to use the database. you can use SqfLite package as a database. but u can also use shared Preferences too. for creating Model use quicktype.io it will create your model with several useful methods such as toJson and fromJson. it will also generate fromRawJson and toRawJson. these two methods work with String. you can convert your model to string and stored to SharedPreferences and when you need it again take it and convert it to model.

How to save data from API temporary in device Flutter

When I open my apps, every time I need to wait for it loading the data from API. I want to save data on Local Storage temporary to make app works offline and also can load the data faster. I want to get data from api, json data and save them to local storage. Can I know what method or can use any package? Thanks in advance
I would recommend using SharedPreferences + JSON. For example, you may have a user object:
class User {
final String name;
final String email;
User(this.name, this.email);
User.fromJson(Map<String, dynamic> json)
: name = json['name'],
email = json['email'];
Map<String, dynamic> toJson() =>
{
'name': name,
'email': email,
};
}
Then what you need to do is:
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("user", jsonEncode(user));
And to recover the object:
SharedPreferences prefs = await SharedPreferences.getInstance();
User user = User.fromJson(jsonDecode(prefs.getString("user")));

How to save cache in device Flutter

I am new in Flutter, this is my first project in Flutter. I want to do a project that once data are loaded from API, they're cached in the device. Next time it can be loaded very fast even if my device is offline. I here that can using Dio package with dio cache manager package for caching server's json response. And then using cache image package to cache images. Anyone can give me some example how to write the code? Thanks in advance
Another best way for caching in flutter is the use of the hive. And it retrieves data faster than Sqflite and Shared preferences
For example, you can check this GitHub repo:https://github.com/shashiben/Anime-details
This will show how to cache the rest API data into the hive and for the next time it will show data from the hive.
I think this answer helped you
Yeah i'd recommend the sqflite package for flutter, i've just figured out how to use it to solve this same issue! I learnt it using this YouTube video: https://youtu.be/1BwjNEKD8g8.
Try shared preferences https://pub.dev/packages/shared_preferences,
Just Decode your response as string and save to sharePreference,
and Encode that String to Object when you need.
import 'package:shared_preferences/shared_preferences.dart';
//storing response as string
SharedPreferences sharedPref = await SharedPreferences.getInstance();
Map decode_options = jsonDecode(jsonString);
String user = jsonEncode(User.fromJson(decode_options));
sharedPref.setString('user', user);//storing
//getting string and converting into Object
SharedPreferences sharedPref = await SharedPreferences.getInstance();
Map userMap = jsonDecode(sharedPref.getString('user')); //retriving
var user = User.fromJson(userMap);
class User {
final String name;
final String age;
User({this.name, this.age});
factory User.fromJson(Map<String, dynamic> parsedJson) {
return new User(
name: parsedJson['name'] ?? "",
age: parsedJson['age'] ?? "");
}
Map<String, dynamic> toJson() {
return {
"name": this.name,
"age": this.age
};
}
}