How to save data from API temporary in device Flutter - 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")));

Related

How to create a FirebaseAuth User from a query from his UID?

I am a bit puzzled about how the Users are managed.
My app successfully creates user accounts via FirebaseAuth whom are creating classified ads.
I need to fetch the owner of the ad from the User UID and so far my code is as follows:
Future<Map<String, dynamic>?> getUser(String uid) async {
final d = await FirebaseFirestore.instance
.collection("User")
.where("id", isEqualTo: uid)
.get();
if (d.docs.isEmpty) return null;
return d.docs.first.data();
}
This code is expected to fetch the given user as a map.
And now, I'd like to convert the Map<String,dynamic> as an actual User instance. But how I should do that?
And is it the right way to go? Because I am wondering whether the User should only be dedicated to the 'authenticated self'.
If I'm right, do you mean the User of the firebase_auth package? You cannot convert Map<String, dynamic> to User. My opinion is to convert it to a model. Take a look at the example below:
class UserModel {
UserModel(
this.id,
this.name,
this.email,
…
);
final String id;
final String name;
final String email;
…
factory UserModel.fromMap(Map<String, dynamic> data, String documentId) {
final String? name = data["name"];
final String? email = data["email"];
…
return UserModel(
documentId,
name ?? "",
email ?? "",
…
);
}
Map<String, dynamic> toMap() => {
"name": name,
"email": email,
…
};
}
UserModel.fromMap(d.docs.first.data(), d.docs.first.id),
UserModel(
"Name",
"Email",
…
).toMap(),

Flutter How Save to List with Shared Preference

How can I save values to a list with SharedPreferences?
It's a simple list with a date and one value, for example, a list of my weight and sorting the list by date.
After searching a lot of articles here you are
For Saving data, must be converted to JSON
SharedPreferences prefs = await SharedPreferences.getInstance();
Map<String, dynamic> user =
{'weight':[60,70],'height':[70,90]};
bool result = await prefs.setString('user', jsonEncode(user));
For Gettin data, must Deconverted from JSON
String userPref = prefs.getString('user');
Map<String,dynamic> userMap = jsonDecode(userPref) as Map<String, dynamic>;
or
final prefs = await SharedPreferences.getInstance();
await prefs.setStringList('items', <String>['Earth', 'Moon', 'Sun']);

Multiple sharedpreference for Multiple users, is it necessary?

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
};
}
}

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;
}

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
};
}
}