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;
}
Related
I am coding a to-do list app in flutter but every time I close the app, all my to-do's are gone, and none of them are stored. How do I stop them from disappearing every time I close the app?
Use sqlite or files. Please refer documentation on cookbooks for either approach.
https://docs.flutter.dev/cookbook/persistence
Your other option is to use an external database over the internet
To persist your data (todo list) you can either
store data on the users device
You can do this by using a local databases like sqflite, sqfentity, shared_preferences etc
or store the data on the server
Using this option you can either spin up your own server or use some quick serverless solutions like supabase or cloud firestore from firebase.
I recommend hive it’s very easy to use and it’s lightweigh.
In addition with all the other propositions, you can try Isar, which is a NoSQL local database that can be used for all platforms:
https://isar.dev/tutorials/quickstart.html
https://pub.dev/packages/isar
Apps generally store data in temporary storage which destroyed every time yo close the app. in order to save data permanently, you could use sqflite database or shared_preferences database
if you want use shared_preferences, you can do this:
first make class that call StorageManager:
import 'package:shared_preferences/shared_preferences.dart';
class StorageManager {
static Future<bool> saveData(String key, dynamic value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.reload();
if (value is int) {
prefs.setInt(key, value);
return true;
} else if (value is String) {
prefs.setString(key, value);
return true;
} else if (value is bool) {
prefs.setBool(key, value);
return true;
} else {
return false;
}
}
static Future<dynamic> readData(String key) async {
final prefs = await SharedPreferences.getInstance();
await prefs.reload();
dynamic obj = prefs.get(key);
return obj;
}
static Future<bool> deleteData(String key) async {
final prefs = await SharedPreferences.getInstance();
return prefs.remove(key);
}
static Future<void> reloadSharedPreferences() async {
final prefs = await SharedPreferences.getInstance();
await prefs.reload();
}
}
then use it like this:
when you want save some thing in storage call this:
await StorageManager.saveData('some unique key', your int or string or bool value);
when you want read from storage:
var result = await StorageManager.readData('some unique key');
if (result != null) {
// use your value
} else {
// this means there is no result
}
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);
}
So I have been trying to load all of my Recent Search history object using shared preferences.
and it doesn't work, it says that "List is not a subtype of List" the error code happens when I call the loadData function. I don't know why my code is not working.
So this is my shared preferences and method code:
void _addLastSearch(String hospitalId,String hospitalName)
{
final lastSearching=SearchModel(hospitalId: hospitalId,hospitalName: hospitalName);
setState(() {
recentSearch.add(lastSearching);
});
}
void savedData() async {
SharedPreferences prefs= await SharedPreferences.getInstance();
prefs.setString('data',jsonEncode(recentSearch));
}
void loadData()async{
SharedPreferences prefs= await SharedPreferences.getInstance();
print("test masul load");
recentSearch=jsonDecode(prefs.getString('data'));
print(recentSearch.length);
}
any im changin the load data function to:
recentSearch=(jsonDecode(prefs.getString('data'))).map((item)=>SearchModel.fromJson(item)).toList();
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
I'm trying to to set a value from sharedpreferences to provider at application start.
this what I have so far, sharedpreferences to widget is working:
https://gist.github.com/andraskende/a19c806aeef0ce88e9a9cafa49660ab4#file-main-dart-L211-L223
Finally i figured out with trial and error... It can be done in the constructor as:
class BarcodeProvider with ChangeNotifier {
BarcodeProvider() {
setup();
}
void setup() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String url = (await prefs.getString('url') ?? '');
_url = url;
notifyListeners();
}
......
}
// global variable, that can be accessed from anywhere
SharedPreferences sharedPrefs;
void main() async { // make it async
WidgetsFlutterBinding.ensureInitialized(); // mandatory when awaiting on main
sharedPrefs = await SharedPreferences.getInstance(); // get the prefs
// do whatever you need to do with it
runApp(MyApp()); // rest of your app code
}