SharedPreference does not read local data in Flutter

In a Flutter project, on clicking the "SignUp" button, I need 2 things,

  1. Saving data to cloud
  2. Saving data to local storage.

I user SharedPreferece to save the data and to retrieve it. The problem is, the data I saved into local storage is available immediately after I Sign Up, but if I hot reload the emulator, the data shows null!

The function by which I saved the data to both cloud and local storage:

Future <void> _saveDataToFirestore(User? currentUser) async{
await FirebaseFirestore.instance.collection("sellers").doc(currentUser!.uid).set({
  "sellerUID": currentUser.uid,
  "sellerName": _fullNameController.text.trim(),
  "sellerAvatarUrl": sellerImageUrl,
  "sellerEmail": currentUser.email,
  "phone": _phoneNumberController.text.trim(),
  "address": completeAddress,
  "status": "approved",
  "earnings": 0.0,
  "lat": position!.latitude,
  "lng": position!.longitude
});

// save 3 data locally
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
await sharedPreferences.setString("uid", currentUser.uid);
await sharedPreferences.setString("email", currentUser.email.toString()); // do not take from controllers, because it will not be null if sign up fail
await sharedPreferences.setString("name", _fullNameController.text);
await sharedPreferences.setString("image", sellerImageUrl);

print("${currentUser.uid},${currentUser.email.toString()}, ${_fullNameController.text}, ${sellerImageUrl} ");}

I initialized SharedPreference in main.dart

    Future <void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SharedPreferences.setMockInitialValues({});
  await SharedPreferences.getInstance();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

The home_screen where I needed the local storage data

    import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:food_fancy_chef/authentication/auth_screen.dart';
import 'package:food_fancy_chef/authentication/login.dart';
import 'package:food_fancy_chef/authentication/register.dart';
import 'package:food_fancy_chef/global/global.dart';
import 'package:shared_preferences/shared_preferences.dart';

class HomeScreen extends StatefulWidget {
  static const routeName = "home_screen";

  @override
  _HomeScreenState createState() => _HomeScreenState();
}


class _HomeScreenState extends State<HomeScreen> {
  String sharedName = "Null value";

  Future<void> _getIntFromSharedPref()async{
    final pref = await SharedPreferences.getInstance();
    final startupName = pref.getString("name");
    if(startupName == null){
      sharedName = "no name";
    } else{
      setState(() {
        sharedName = startupName;
      });

    }

  }

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

  @override
  void didChangeDependencies() {
    _getIntFromSharedPref();
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        flexibleSpace: Container(
          decoration: const BoxDecoration(
              gradient: LinearGradient(
                  colors: [
                    Colors.cyan,
                    Colors.amber
                  ],
                  begin: FractionalOffset(0.0, 0.0),
                  end: FractionalOffset(1.0, 1.6),
                  stops: [0.0,1.0],
                  tileMode: TileMode.mirror
              )
          ),
        ),
        title: Text(
          sharedName // I need "name" from local storage
          //   sharedPreferences!.getString("name")! == null? "null value":sharedPreferences!.getString("name")!
        )
      ), 
      body: Column(
        children: [
          Center(
            child: ElevatedButton(
              onPressed: (){
                setState(() {
                  firebaseAuth.signOut();
                  Navigator.pushReplacement(context, MaterialPageRoute(builder: (c)=> LoginScreen()));
                });

              },
              child: Text("Log Out"),
            ),
          ),
          Center(
            child: ElevatedButton(
              onPressed: (){
                setState(() {
                  firebaseAuth.signOut();
                  Navigator.pushReplacement(context, MaterialPageRoute(builder: (c)=> AuthScreen()));
                });

              },
              child: Text("signout"),
            ),
          ),
        ],
      ),
    );
  }
}

What I have tried:

  1. I have tried to get the data directly without any init() method, it returns null:

    sharedPreferences!.getString("name")! == null? "null value":sharedPreferences!.getString("name")!
    
  2. I have declared the variable first and assigned the value via a function run at init(), code is below.

  3. I tried the same process above but with didChangeDependencies() method.

  4. I used both init() and didChangeDependencies()

  5. I deleted the emulator and reinstalled it.

I also saved SharePreferences() in a global.dart file, so that, I can access them anywhere in the project.

before and after "Restarting emulator "

3 answers

  • answered 2022-01-13 05:22 Varun Kumar

    Try this

    Future<void> _getIntFromSharedPref() async{
        SharedPreferences? pref = await SharedPreferences.getInstance();
        String startupName = pref!.getString("name") ?? 'no name';
        setState(() {});
        }
    

  • answered 2022-01-13 06:35 Pranav

    Try removing SharedPreferences.setMockInitialValues({}); from main.dart.

  • answered 2022-01-13 06:36 Saddan

    When hot restart the widget tree re built it means only this Widget build(BuildContext context) method triggered. initState is called only once for a widget and didChangeDependencies may be called multiple times per widget lifecycle. So initializing some thing on didChangeDependencies you have to be careful. Calling like this will resolve your issue whille hot restart

    @override
    Widget build(BuildContext context) {
    _getIntFromSharedPref();
    return Scaffold(
       );
    }
     
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum