This is a login, that catch user data and write in the other pages, like his name, etc
I set sharedPreference here:
Future<bool> login() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
SharedPreferences nome = await SharedPreferences.getInstance();
var email = _emailController.text;
var senha = _senhaController.text;
var auth = 'Basic ' + base64Encode(utf8.encode('$email:$senha'));
var url = Uri.parse("http://177.70.102.109:3005/autenticacao");
var resposta = await http.get(
url,
headers: (<String, String>{'authorization': auth}),
);
// List campos = [];
if (resposta.statusCode == 200) {
await sharedPreferences.setString(
'token', "Token ${jsonDecode(resposta.body)['token']}");
await nome.setString(
'nome', "${jsonDecode(resposta.body)['result'][0]['nome']}");
print(nome);
return true;
} else {
return false;
}
}
And i want to receive and pass the 'nome' to a TextWidget in another class.
In the other page you can write something like that:
class ExamplePage extends StatefulWidget {
const ExamplePage({Key? key}) : super(key: key);
#override
State<ExamplePage> createState() => _ExamplePageState();
}
class _ExamplePageState extends State<ExamplePage> {
final _controller = TextEditingController();
#override
void initState() {
initNome();
super.initState();
}
Future<void> initNome() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
String _nome = sharedPreferences.getString("nome", "");
_controller.text = _nome;
}
#override
Widget build(BuildContext context) {
return Text(_controller.text)
}
}
To read the value in some other widget you can use
getString https://pub.dev/documentation/shared_preferences/latest/shared_preferences/SharedPreferences/getString.html
Implementation would be similar to this:
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
Text(sharedPreferences.getString("nome");
See this post for example:
Flutter Shared Preference in Text Widget
Related
SharedPreferences prefs;
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
Above is how it is initialized
prefs.setString('emailPrefs1', email).then((bool success) {
print('${prefs.getString('emailPrefs1')}');
});
Value is set successfully after this
_getPrefs() async {
prefs = await _prefs;
String emailPrefs1 = prefs.getString('emailPrefs1');
if (emailPrefs1 != null) {
setState(() {
emailController.text = emailPrefs1;
});
}
print(emailPrefs1);
}
But it returns null after initializing this activity in init state.
#override
void initState() {
super.initState();
_getPrefs();
}
I am using shared_preferences: ^0.5.6 version.
if you are sure your 'emailPref' is set, this should work:
class _MyHomePageState extends State<MyHomePage> {
TextEditingController _emailController;
SharedPreferences _prefs;
Future<SharedPreferences> _getPrefs() async{
return await SharedPreferences.getInstance();
}
#override
void initState(){
super.initState();
_emailController = TextEditingController();
_getPrefs().then((prefs){
_prefs = prefs; //If you need your SharedPreference Object later on
_emailController.text = prefs.getString('emailPrefs1');
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(child: Text(_emailController.text))
);
}
#override
void dispose() {
super.dispose();
_emailController.dispose();
}
}
How is the private _prefs being initialized? You can either share more of your code or just pull the value from what you definitely saved to.
void getPrefs() async {
prefs = await SharedPreferences.getInstance(); // this is what you saved to
String emailPrefs1 = prefs.getString('emailPrefs1');
print(emailPrefs1);
if (emailPrefs1 != null) {
setState(() {
emailController.text = emailPrefs1;
});
}
}
You can also print the value straight from the instance when you do save to confirm a successful save.
prefs.setString('emailPrefs1', email).then((bool success) {
print('${prefs.getString('emailPrefs1')}');
});
I have a page with this code:
class _HomeScreenState extends State<HomeScreen> {
bool isFirstLoading = true;
#override
void initState() {
super.initState();
if (isFirstLoading) {
getInfo();
setState(() {
isFirstLoading = false;
});
} else {
getInfoFromSharedPref();
}
}
Future<http.Response> getInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
Loader.show(context,
isAppbarOverlay: true,
isBottomBarOverlay: true,
progressIndicator: CircularProgressIndicator());
var url = kLinkAPI + "/getInfo";
var response =
await http.post(url, headers: {"Content-Type": "application/json"});
var resObj = jsonDecode(response.body);
if (response != null) {
setState(() {
if (resObj.length > 0) {
address = resObj[0]['address'];
countryInfo = resObj[0]['country_info'];
phone = resObj[0]['phone'];
latitude = resObj[0]['latitude'];
longitude = resObj[0]['longitude'];
isFirstLoading = false;
prefs.setString('address', address);
prefs.setString('countryInfo', countryInfo);
prefs.setString('phone', phone);
prefs.setString('latitude', latitude);
prefs.setString('longitude', longitude);
}
});
}
Loader.hide();
}
void getInfoFromSharedPref() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
address = prefs.getString('address');
countryInfo = prefs.getString('countryInfo');
phone = prefs.getString('phone');
latitude = prefs.getString('latitude');
longitude = prefs.getString('longitude');
});
}
}
I would like to make sure that the first time I enter the page, the isFirstLoading variable is set to false and then calls the getInfo function with the http call while if it is false it takes from the shared preferences.
isFirstLoading is now always true
how could I solve?
I think you're overcomplicating your code. Let me know if this solves your issue.:
class _HomeScreenState extends State<HomeScreen> {
SharedPreferences prefs;
#override
void initState() {
super.initState();
getInfo();
}
// ...
}
Now, the first time this widget is inserted into the tree:
initState() will be called once.
Therefore, getInfo() will be called. getInfo() will make the http call and update the prefs variable using setState, which you have already done.
Whenever the widget is reloaded, the prefs variable will not be lost since it is a stateful widget.
Next, if you would like to save the preference settings locally instead of making an http call every time the user opens the app, you should handle that inside of getInfo() itself. Something like this:
getInfo() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (prefs.getBool("isFirstLoading") == false) {
// setState to update prefs variable
} else {
// make http call
// save prefs (optional)
// setState to update prefs variable
}
}
If I undestand correctly, you are trying to only call the getInfo method on the first load, and the getInfoFromSharedPref all the other time.
My suggestion is to save the isFirstLoading bool as a preference like so:
class _HomeScreenState extends State<HomeScreen> {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isFirstLoading = prefs.getBool("isFirstLoading") ?? true;
#override
void initState() async {
super.initState();
if (isFirstLoading) {
await getInfo();
await prefs.setBool("isFirstLoading", false);
isFirstLoading = false;
} else {
getInfoFromSharedPref();
}
}
Future<http.Response> getInfo() async {
// …
}
void getInfoFromSharedPref() async {
// …
}
}
I have a code for getting current logged in username and save it to a shared preference. The issue am facing is that whenever a user logs in for the first time, the username is never displayed, but when I do ahot reload on the app, the username is displayed on the screen . How can I have it in such a way the username is loaded on the first load without doing a hot reload.
How am getting the username on SharedPreference
/// Gets the current and prior accounts.
Future<dynamic> handleGetAccount() async { // <-- Replace dynamic with type of currentAccount
final result = await msal.getAccount();
if (result.currentAccount != null) {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("username", result.currentAccount.username);
//print(result.currentAccount.username);
return result.currentAccount;
} else {
print('no account found');
return null;
}
}
My navigation to NavScreen ->redirects to Home screen
/// Updates the signed in state
refreshSignedInStatus() async {
bool loggedIn = await msal.getSignedIn();
if (loggedIn) {
isSignedIn = loggedIn;
if(isSignedIn) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => NavScreen(
),
),
);
}
// Remaining code for navigation
}
}
how I am getting the username to show on home screen and show the username
class Home extends StatefulWidget {
const Home({Key key}) : super(key: key);
#override
HomeState createState() => new HomeState();
}
class HomeState extends State<Home> {
final TrackingScrollController _trackingScrollController =
TrackingScrollController();
String username = "";
#override
void initState() {
getName();
}
Future<String> getName() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
username = prefs.getString("username");
return username;
}
Because getName() is a async method, you should call setState((){}) after username got.
void getName() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
username = prefs.getString("username");
setState((){});
}
I am new in flutter.I try to learn SharedPreferences and i have this exception.
How can i solve this?
class _MyAppState extends State {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
RaisedButton(
onPressed: () {addStringToSF();},
),
Text(getStringValuesSF()),
],
),
);
}
addStringToSF() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('stringValue', "abc");
}
getStringValuesSF() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String stringValue = prefs.getString('stringValue');
return stringValue;
}
}
default async function return dynamic we have to do type casting
Future<String> getStringValuesSF() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String stringValue = prefs.getString('stringValue');
return stringValue;
}
I will just extend answer from #Abhishek as I needed similar but didn't work as epxected on TextFormField.
So I made up a bare loadString method to get any kind of key from sharedPrefs:
Future<String> loadString(String key) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(key) ?? '';
}
Next in the same class I created init form void to use above method (I still think this way of working with Future is bit not optimal in Dart, anyway..), this will load data into controller:
Future<void> _initForm() async {
final clientBusinessRegistrationID = await loadString('clientBusinessRegistrationID');
_clientBusinessRegistrationIDController.value =
_clientBusinessRegistrationIDController.value.copyWith(
text: clientBusinessRegistrationID);
}
I also added this block in same class:
SharedPreferences? preferences;
Future<void> initializePreference() async{
preferences = await SharedPreferences.getInstance();
}
and finally in initState() I call it and it works:
#override
void initState() {
super.initState();
// setupLocator();
initializePreference().whenComplete((){
setState(() {});
});
_clientBusinessRegistrationIDController.text = 'Initial';
_initForm();
}
Where am I going wrong?
I have login with google to get the token and send it to graphgl, this token is saved (it was meant to be) in sharedpreferences, but it is not saving, I have the following action (mobx).
#action
Future loginWithGoogle() async {
user = await _authRepository.getGoogleLogin();
final idToken = await user.getIdToken();
print('Bearer ${idToken.token}');
sharedPreferenceService.setToken('Bearer ${idToken.token}');
}
Services shared.
class SharedPreferenceService {
SharedPreferences _prefs;
Future<bool> getSharedPreferencesInstance() async {
_prefs = await SharedPreferences.getInstance().catchError((e) {
print("shared prefrences error : $e");
return false;
});
return true;
}
Future setToken(String token) async {
await _prefs.setString('token', token);
}
Future clearToken() async {
await _prefs.clear();
}
Future<String> get token async => _prefs.getString('token');
}
SharedPreferenceService sharedPreferenceService = SharedPreferenceService();
Action login in view.
#action
Future loginWithGoogle() async {
try {
loading = true;
await auth.loginWithGoogle();
Modular.to.pushReplacementNamed('/index');
} catch (e) {
loading = false;
}
}
The login happens normal but it accuses error when it goes to index, informing that it received null the getString("token").
I/flutter ( 3198): ClientException: Unhandled Failure NoSuchMethodError: The method 'getString' was called on null.
I/flutter ( 3198): Receiver: null
I/flutter ( 3198): Tried calling: getString("token")
This token string is not being saved.
Sorry for bad english
Just copied your code and made some changes just check:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
SharedPreferenceService sharedPreferenceService = SharedPreferenceService();
#override
void initState() {
super.initState();
loginWithGoogle();
getSharedValues();
}
getSharedValues() async{
bool value = await sharedPreferenceService.getSharedPreferencesInstance();
if(value)
print(await sharedPreferenceService.token);
}
loginWithGoogle() async {
// this is the where you get your bearer, but time being I have taken sample bearer
String token =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJZb3VuaXNaYXJnYXIiLCJlbWFpbCI6InlvdW5pc0BiYXh0dXJlLmNvbSIsImp0aSI6IjlhNjc2OTVlLTBiZmEtNDdmMy04ZTVlLWVhYWMzY2VmNmRlOSIsIklkIjoiMSIsIkVtYWlsIjoieW91bmlzQGJheHR1cmUuY29tIiwiZXhwIjoxNTgzODQ2ODU0LCJpc3MiOiJQYWNpZmljIFByaW50aW5nIiwiYXVkIjoiUGFjaWZpYyBQcmludGluZyJ9.CKxBwAB7YeOKJRmoCg4_JAhJKHP2qXb7KJXPysqmbAs';
bool value = await sharedPreferenceService.getSharedPreferencesInstance();
if (value == true) {
sharedPreferenceService.setToken('Bearer $token');
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(home: Scaffold(body: Center(child: Text('sample'))));
}
}
class SharedPreferenceService {
SharedPreferences _prefs;
Future<bool> getSharedPreferencesInstance() async {
_prefs = await SharedPreferences.getInstance().catchError((e) {
print("shared prefrences error : $e");
return false;
});
return true;
}
Future setToken(String token) async {
await _prefs.setString('token', token);
}
Future clearToken() async {
await _prefs.clear();
}
Future<String> get token async => _prefs.getString('token');
}
Thank you very much, I made the correction in the action.
#action
Future loginWithGoogle() async {
user = await _authRepository.getGoogleLogin();
final idToken = await user.getIdToken();
print('Bearer ${idToken.token}');
bool value = await sharedPreferenceService.getSharedPreferencesInstance();
if (value == true) {
sharedPreferenceService.setToken('Bearer ${idToken.token}');
}
}