Shared Preferences key value not changing

101

Your are calling initializePreference() inside initState() and that function set hasLoggedIn to false. So even if you set it to true in your login page, when restarting the app it will be set again to false.

Share:
101
Danah
Author by

Danah

Updated on December 01, 2022

Comments

  • Danah
    Danah over 1 year

    I want to write code that directs the user to a welcome page if it's the first time the app is being run. After the user logs in, any subsequent launches of the app direct the user to log in, skipping the welcome page. It seems that when I try to set the value of my key upon logging in, it's not changing, because after logging in, closing the app and launching it again it's still going to the welcome page. How do I fix this? I'm not sure whether the issue is with the initialisation or the setting of the value upon login.

    Here's the initialisation of my app:

    import 'package:screens/welcomepages/signup_or_login.dart';
    import 'package:screens/welcomepages/welcome.dart';
    import 'package:firebase_core/firebase_core.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:config/theme.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    
    Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
    
    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp();
      SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
          statusBarColor: Colors.transparent,
          statusBarBrightness: Brightness.dark));
      runApp(MyApp(prefs: await _prefs));
    }
    
    class MyApp extends StatefulWidget {
      const MyApp({Key? key, this.title, required this.prefs})
          : super(key: key);
      final String? title;
      final SharedPreferences prefs;
    
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      late SharedPreferences prefs;
    
      @override
      void initState() {
        super.initState();
        initializePreference();
      }
    
      Future<void> initializePreference() async {
        prefs = await SharedPreferences.getInstance();
        setState(() {
          prefs.setBool("hasLoggedIn", false);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        if (prefs.getBool("hasLoggedIn") == false) {
          return MaterialApp(
            theme: theme(),
            debugShowCheckedModeBanner: false,
            home: Welcome(prefs: prefs),
          );
        }
        return MaterialApp(
          theme: theme(),
          debugShowCheckedModeBanner: false,
          home: SignUpOrLogIn(prefs: prefs),
        );
      }
    }
    

    And here's the relevant parts of my log in page

    import 'package:services/auth/auth_service.dart';
    import 'package:widgets/text_fields_widgets/email_textfield.dart';
    import 'package:widgets/text_fields_widgets/password_textfeild.dart';
    import 'package:flutter/material.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    
    class Login extends StatefulWidget {
      const Login({Key? key, required this.prefs}) : super(key: key);
      final SharedPreferences prefs;
    
      @override
      _LoginState createState() => _LoginState(prefs);
    }
    
    class _LoginState extends State<Login> {
      late final SharedPreferences prefs;
      _LoginState(SharedPreferences prefs);
    
      Future<void> initializePreference() async {
        prefs = await SharedPreferences.getInstance();
      }
    
      @override
      void initState() {
        super.initState();
        initializePreference().whenComplete(() {
          setState(() {
            prefs.getBool("isFirstRun");
          });
        });
      }
    
     @override
      Widget build(BuildContext context) {
        Material btnLogin = loginBTN(context);
        return Scaffold(
          .....
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: btnLogin,
          )
        }
    
      Material loginBTN(BuildContext context) {
        // ignore: unused_local_variable
        final btnLogin = Material(
          elevation: 5,
          borderRadius: BorderRadius.circular(30),
          color: Theme.of(context).primaryColor,
          child: MaterialButton(
            padding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
            minWidth: MediaQuery.of(context).size.width,
            onPressed: () async {
              setState(() {
                prefs.setBool("hasLoggedIn", true);
              });
              setState(
                () => loadingAnimation = true,
              );
              await Future.delayed(const Duration(seconds: 1));
              setState(
                () => loadingAnimation = false,
              );
              await Authservice().logInMethod(
                  emailController.text, passwordController.text, context, _formKey);
            },
            child: loadingAnimation
                ? const CircularProgressIndicator(
                    color: Colors.white,
                  )
                : const Text(
                    "Log in",
                    textAlign: TextAlign.center,
                    style: TextStyle(fontSize: 24, color: Colors.white),
                  ),
          ),
        );
        return btnLogin;
      }
    }
    

    Sorry for how lengthy this is, tried to shorten it to only provide what's relevant.

    • Danah
      Danah about 2 years
      I get the error "The non-nullable variable '_prefs' must be initialized. Try adding an initializer expression." if I don't initialise outside the main function.
    • Danah
      Danah about 2 years
      "A value of type 'Future<SharedPreferences>' can't be assigned to a variable of type 'SharedPreferences'. Try changing the type of the variable, or casting the right-hand type to 'SharedPreferences'."
  • Danah
    Danah about 2 years
    Unfortunately, the issue is still there.