Search code examples
flutterdartsharedpreferences

How to store and pass SharedPreference value to other pages in flutter?


When user logs into the app I need to set 'PWD' in the shared_preference variable. I need to get that value in splashcreen of my app so that when user opens the app again it need redirect to only password entering page. How can I do it in flutter.

onPressed: () async {
            SharedPreferences prefs = await SharedPreferences.getInstance();
            appdata.loginmode = prefs.setString('LOGIN_MODE', 'PWD');

            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => BottomNavigation()),
            );
            print('Shared....');
            print(prefs.getString('LOGIN_MODE'));
          },

This what I am doing when user click login it will set to 'PWD', then I need to call the prefs in splashscree.


Solution

  • Short Answer

    Not for splash screen but I am using the same logic for the onboard screen. I hope this answer will help. So, on your main.dart file, create a nullable int onBoardCount, outside of any class, you're gonna need this on your splash screen. Also, instantiate SharedPreferences in main and pass it with onboardcount to you MyApp();

     int? onBoardCount;     
        void main() async {
          WidgetsFlutterBinding.ensureInitialized();
          SharedPreferences prefs = await SharedPreferences.getInstance();
        // Get onboard count from prefs, if it already exists,if not it will return null
          onBoardCount = prefs.getInt('onBoardKey');  
        
          runApp(MyApp(prefs,onBoardCount));
        }
    

    Now, your MyApp file should be something like

    class MyApp extends StatefulWidget {
      late SharedPreferences prefs;
    ....
    MyApp(this.prefs,this.onBoardCount, ...);
    

    Now in your splash_screen.dart use the following logic.

     void onSubmitDone(AppStateProvider stateProvider, BuildContext context) {
            await prefs.setInt('onBoardKey', 0);
           // Some route logic like route.push("/home");
          }
    

    Long Answer

    I am using Go Router for routing and Provider for state management so, here's my app's code.

    Main.dart

    int? onBoardCount;
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      SharedPreferences prefs = await SharedPreferences.getInstance();
    
      onBoardCount = prefs.getInt('onBoardKey');
    
        ....
      runApp(MyApp(prefs, onBoardCount));
    }
    

    I have a separate MyApp file to reduce congestion.

    my_app.dart

    class MyApp extends StatefulWidget {
      late SharedPreferences prefs;
      int? onBoardCount;
      
    
      MyApp(this.prefs, this.onBoardCount,..... {Key? key})
          : super(key: key);
    
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
    // The appstate provider is handling app level state
      late AppStateProvider appStateProvider;
    
         @override
      void didChangeDependencies() {
        super.didChangeDependencies();
        appStateProvider = AppStateProvider(
            widget.onBoardCount, widget.prefs,....);
      }
    
     
    
      @override
      Widget build(BuildContext context) {
        return MultiProvider(
          providers: [
           ....
            ChangeNotifierProvider(
                create: (context) => AppStateProvider(
                    widget.onBoardCount,
                    widget.prefs,...)),
                   
            Provider(
              create: (context) => AppRouter(
                appStateProvider: appStateProvider,
                onBoardCount: widget.onBoardCount,
                prefs: widget.prefs,
              ),
            ),   
            
          ],
          child: Builder(
            builder: ((context) {
              final GoRouter router = Provider.of<AppRouter>(context).router;
    
              return MaterialApp.router(
                  routeInformationParser: router.routeInformationParser,
                  routerDelegate: router.routerDelegate);
            }),
          ),
        );
      }
    }
    

    App State Provider File

    Create a function to update onboard logic and notify listeners.

    class AppStateProvider with ChangeNotifier {
      AppStateProvider(this.onBoardCount, this.prefs,..);
      
      int? onBoardCount;
      late SharedPreferences prefs;
     
    
      bool? _isOnboarded;
      
    
      bool get isOnboard => _isOnboarded as bool;
     
      void hasOnBoarded() async {
        await prefs.setInt('onBoardKey', 0);
        _isOnboarded = true;
    
        notifyListeners();
      }
    
      }
    

    On Router file

    class AppRouter {
      late AppStateProvider appStateProvider;
      late SharedPreferences prefs;
      
      int? onBoardCount;
    
      AppRouter({
        required this.appStateProvider,
        required this.onBoardCount,
        required this.prefs,
      });
      get router => _router;
    
      late final _router = GoRouter(
          refreshListenable: appStateProvider,
          initialLocation: "/",
          routes: [
            ...
          ],
          redirect: (state) {
            final String onboardLocation =
                state.namedLocation("Your Route name");
    
           
    
            bool isOnboarding = state.subloc == onboardLocation;
          
            bool? toOnboard = prefs.containsKey('onBoardKey') ? false : true;
         
            
    
            print("Is LoggedIn is $isLoggedIn");
            if (toOnboard) {
            return isOnboarding ? null : onboardLocation;
            }
    
            return null;
          });
    }
    

    Since the router is listening to appStateProvider, it will change once you call hasOnBoarded() on your onboard screen.

    OnBoardScreen

    void onSubmitDone(AppStateProvider stateProvider, BuildContext context) {
        stateProvider.hasOnBoarded();
        GoRouter.of(context).go("/");
      }
    

    I hope this will help please leave comments. FYI, ... is some other codes that I feel it's not important for this topic.