I have a simple question regering the shared_preferences package in flutter.
Is it safe to get an instance of SharedPreferences and store that for future use or is it best to always get a new reference each time?
To clarify, which of these two are the proper or best way of doing it?
SharedPreferences preferences;
void init() async {
preferences = await SharedPreferences.getInstance();
}
void setValue(String key, String value) async{
await preferences.setString(key, value);
}
void setValue(String key, String value) async {
final preferences = await SharedPreferences.getInstance();
await preferences.setString(key, value);
}
Related
I have next piece of flutter code, to get shared preference key-value
I do understand why _blueUriInit is always NULL
I assume that you are forgot to provide the value for that key before call to get its value, you need to first assign value to it first:
Future<bool> saveData(String key, dynamic value) async {
final prefs = await SharedPreferences.getInstance();
return prefs.setString(key, value);
}
and call it like this:
void initState() {
saveData('blueUri', 'test');
setState(() {
_blueUriInit = getValue('blueUri');
});
super.initState();
}
now next time you open your app, getValue should return you test.
you can create this function for setting value
static setUserID(String key, String value) async {
final SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.setString(key, value);
}
Use case :
await SharedValue.setUserID("Email", "demo#gmail.com");
And For getting value from shared preference you can use this function
static Future<String?> getUserID(String key) async {
final SharedPreferences preferences = await SharedPreferences.getInstance();
return preferences.getString(key);
}
Use case :
userName = await SharedValue.getUserID("Email");
First you need to setString with key and value (name is key)
Future setValue() async {
final prefs = await SharedPreferences.getInstance();
prefs.setString("name", "Hitarth");
}
getString with key (here i took "name" as key)
Future getValue(String key) async {
final prefs = await SharedPreferences.getInstance();
String value = prefs.getString(key) ?? "NULL";
return value;
}
store in variable callin getValue
void initState() {
setState(() {
_blueUriInit = getValue("name");
});
super.initState();
}
I am using shared_preferences: ^2.0.15 and saving my values locally.
When I change my screen and get my values, I get an error.
How can I initialize SharedPreferences correctly?
Video
late SharedPreferences _preferences;
#override
void initState() {
super.initState();
getLocalData();
}
Future getLocalData() async {
_preferences = await SharedPreferences.getInstance();
}
I've checked the video you shared.
You're just missing to call the getLocalData method inside the LoginViewModel.
I'd suggest adding a line inside your loginRequest method to call getLocalData method. Well, don't forget to await.
await getLocalData();
That's it :)
actually you are not fetching data from your shared preference
you have to get the data that u saved
first set data that you want to save
addStringToSF() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('email', "email#email.com");
}
then in your second screen you can get your data
late SharedPreferences _preferences;
late String email;
#override
void initState() {
super.initState();
getLocalData();
}
Future getLocalData() async {
_preferences = await SharedPreferences.getInstance();
// for exemple you saved a string value with key ='email'
email= _preferences.getString('email');
}
check this : https://medium.flutterdevs.com/using-sharedpreferences-in-flutter-251755f07127
I'm trying to show a page as an initial login, this is only displayed when my switch value is set to true.
The switch value is stored with shared preferences but when I open the application it is not recovered, only after an application update is it actually recovered. how can i get it to be recovered instantly when i open my application?
below the code:
Future<bool> saveSwitchState(bool value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool("switched", value);
print('Switch Value saved $value');
return prefs.setBool("switched", value);
}
Future<bool> getSwitchState() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
SettingsPage.switched = prefs.getBool("switched")!;
print(SettingsPage.switched);
return SettingsPage.switched;
}
on another page then the value that is actually recovered:
if(AuthPage.authenticated == false && SettingsPage.switched == true ) {
yield ProfileNoAuth();
return; }
you can use dependency injection follow these steps :
get it package
create a Separate dart containing the following code file like this:
GetIt locator = GetIt.instance;
Future<void> setupLocator() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
locator.registerLazySingleton<SharedPreferences>(() => sharedPreferences);
}
call the setupLocator() method and wait for it in your main function
void main() async {
await setupLocator();
runApp(App());
}
access SharedPreferences Instance from anywhere like this:
locator();
now the SharedPreferences Instance if available anywhere in your project
please note that you dont have to wait for getting the Instance anymore, because you have only one Instance sharable across the application
bool getSwitchState() {
final prefs = locator<SharedPreferences>();
SettingsPage.switched = prefs.getBool("switched")!;
print(SettingsPage.switched);
return SettingsPage.switched;
}
I've create an initState in my page and call callData to get favId (type : List) every I open this page. But, when the application start, my compiler show this error message :
_TypeError (type 'List<String>' is not a subtype of type 'String')
and this is my getData's function :
getData(favId) async {
SharedPreferences pref = await SharedPreferences.getInstance();
return pref.getStringList(favId);
}
also this is my saveData's function :
void saveData() async {
SharedPreferences pref = await SharedPreferences.getInstance();
pref.setStringList("id", favId);
}
How to fix this problem and I can call getData every I open this page in my application?
Thank you :)
if you want to save and retrieve List to and from SharedPreferences, you to use same key to save and retrieve the value.
here is a simple example,
const favKey = 'favoriteKey';
To save data,
void saveData(String favKey, List<String> favorites) async {
SharedPreferences pref = await SharedPreferences.getInstance();
pref.setStringList(favKey,favorites);
}
To retrive data,
getData(String favKey) async {
SharedPreferences pref = await SharedPreferences.getInstance();
return pref.getStringList(favKey);
}
Note: You need to use same key to set and get data using SharedPreference.
"id" is a String, you need to store a List<String> into setStringList
There are the steps if you want to add an item to the list:
List<String> ids = await getData(favId);
ids.add("id");
saveData(ids, favId);
then change the saveData() to
void saveData(ids, favId) async {
SharedPreferences pref = await SharedPreferences.getInstance();
pref.setStringList(ids, favId);
}
getData()
List<String> getData(favId) async {
SharedPreferences pref = await SharedPreferences.getInstance();
return pref.getStringList(favId);
}
Although I set the _sharedPreferences in the constructor, it gets null in getUsername. I don't know missing what:
class PreferencesProvider {
SharedPreferences _sharedPreferences;
PreferencesProvider() {
SharedPreferences.getInstance().then((prefs) => _sharedPreferences = prefs);
}
String getUsername() {
return _sharedPreferences.getString("Username");
}
String getX() {
return _sharedPreferences.getString("X");
}
String getY() {
return _sharedPreferences.getString("Y");
}
String getZ() {
return _sharedPreferences.getString("Z");
}
}
alternatively it didn't work either:
class LoginProvider {
SharedPreferences _sharedPreferences;
LoginProvider._internal();
static final LoginProvider _instance = LoginProvider._internal();
factory LoginProvider() {
_instance.initPreferences();
return _instance;
}
initPreferences() async {
_sharedPreferences = await SharedPreferences.getInstance();
}
I want to use this in MaterialApp:
initialRoute: PreferencesProvider().isLoggedIn() ? "MainPage" : "LoginPage"
Edit: I know I should use await. But then keyword isn't same? I don't want to wait the instance again for all returns. In the other hand, I can't use await in initialRoute.
The way i manage to login the user for my application for the similar scenario is,
String startPage="LoginPage";
void main() {
SharedPreferences prefs = await SharedPreferences.getInstance();
String user=prefs.getString("Username");
if(user!=null && user.length>0){
startPage="MainPage";
}
runApp(MyApp());
}
Now, set your initialRoute as follow,
initialRoute: startPage,
This solution works in every scenario because i am fetching the data before the runApp() function in my application. Your application renders your initialPage after calling the runApp() function.
This is the best way to manage your login page based on data retrieval from the sharedpreferences as SharedPreferences takes time to fetch the data. Till the data is retrieved from sharedpreferences your build method gets completed its UI rendering.
While using preferences you should use Future, await and async
Future<String> getUsername() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String storeUserDetails = prefs.getString("Username");
return (storeUserDetails != null);
}
Hope this helps!
You need to wait a little bit for get username from shared preferences. getInstance is an async process.
Below code will work, because getString will work after getInstance
Future<String> getUsername() async {
_sharedPreferences = await SharedPreferences.getInstance();
return _sharedPreferences.getString("Username");
}
You need to modify your PreferencesProvider class