Search code examples
androidflutterdartmobilesharedpreferences

Use Shared Preferences in Flutter to data between differente route?


i have a little problem that make me crazy. I created a First Time Open section in my Flutter App that controlled by a flag in my SharedPreferences like this:


Future<void> main() async{
  WidgetsFlutterBinding.ensureInitialized();
  SharedPreferences preferences = await SharedPreferences.getInstance();
  initScreen = preferences.getInt('initScreen');
  if (initScreen == 0 || initScreen == null) {
    await preferences.setInt('initScreen', 1);
    await preferences.setString('email', "");
    await preferences.setString('firstName', "");
    await preferences.setString('lastName', "");
    await preferences.setString('phoneNumber', "");
    await preferences.setString('address', "");
  }
  runApp(MyApp());
}

/*
void main() {
  runApp(MyApp());
}
*/

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'My Title',
      theme: theme(),
      //initialRoute: SplashScreen.routeName,
      initialRoute: initScreen == 0 || initScreen == null ? '/splash' : '/dashboard',
      routes: routes,
    );
  }
}

In the First Time Section that i want to show there is the Login/Register form. So when the users insert their istances i want to save that in my SharedPreference:

class _SignFormState extends State<SignForm> {
  ...
  String email;
  SharedPreferences preferences;
  
  Future<void> initSharedPreferences() async{
    preferences = await SharedPreferences.getInstance();
  }

  Future<void> setEmail(String value) async{
    preferences.setString('email', value);
  }
  
  Future<void> setInitScreenState(int value) async{
    preferences.setInt('initScreen', value);
  } 

  ...
  DefaultButton(
    text: "Continue",
    press: () {
      if (_formKey.currentState.validate()) {
        _formKey.currentState.save();
        // If all are valid then go to success screen
        setEmail(email);
        setInitScreenState(1);
        Navigator.pushNamed(context, LoginSuccessScreen.routeName);
      }
    },
  ),

Then in the dashboard i want to display for example the email that was insert in the preview route, or when the user re-open my app after he left and close it.

class Body extends StatefulWidget {
  @override
  _BodyState createState() => _BodyState();
}

class _BodyState extends State<Body> {

  int initScreen;
  String email;
  SharedPreferences preferences;

  Future<void> initSharedPreferences() async{
      preferences = await SharedPreferences.getInstance();
  }

  Future<void> getSharedPreferences() async{
    initScreen = await preferences.getInt('initScreen') ?? 0;
    email = await preferences.getString('email') ?? 'Email not found';
  }

  @override
  void initState() {
    initSharedPreferences();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    getSharedPreferences();

    return SingleChildScrollView(
      child: Center(
        child: Padding(
          padding: EdgeInsets.all(kDefaultPadding),
          child: Column(
            children: [
              Text("Dashboard temp.\n"),
              Text("$initScreen"),
              Text("$email"),
              SizedBox(height: kDefaultPadding,),
              MaterialButton(
                child: Text("Logout", style: TextStyle(color: kWhiteColor, fontSize: 18),),
                onPressed: () {},
                height: kDefaultPadding,
                color: kPrimaryColor,
                padding: EdgeInsets.symmetric(horizontal: kDefaultPadding, vertical: 10.0),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

But it doesn't work. And the function "preferences.getInt('initScreen') ?? 0;" or "preferences.getString('email') ?? 'Email not found';" always get my Null Error.

[VERBOSE-2:ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: The method 'getInt' was called on null.
Receiver: null
Tried calling: getInt()

Thank you so much to read this question and if you leave a comment. Have a nice day


Solution

  • This is because your function initSharedPreferences() is a future and when getSharedPreferences() is called it has not resolved yet. Try getting your instance of sharedPreferences in getSharedPreferences() and also use setState() to update the value of email