Home > Software engineering >  SharedPreference does not read local data in Flutter
SharedPreference does not read local data in Flutter

Time:01-14

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 "

CodePudding user response:

Try this

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

CodePudding user response:

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

CodePudding user response:

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(
   );
}
 
  •  Tags:  
  • Related