flutterdartflutter-sharedpreference

Not able to see sharedpref folder in phone as well Getting this error :Exception has occurred. _CastError (Null check operator used on a null value)


Hello Guys I am new to flutter and working on a flutter project. Below is the code of my splash screen. What I am doing is when the app launched we get the data from sharedpreference if we got the data we attempt to login from the data if it's successfull then whe move to homescreen else if there is no data or attempt was failed due tou any reason we move to home screen. Right now I haven't added the check for if data is empty so ignore it. The error I am getting in getData it states that Exception has occurred. _CastError (Null check operator used on a null value)

Here is the code:

String password = '';
String email = '';

void getData() async {
  email = (await sharedPreference().getCred('email'))!;
  password = (await sharedPreference().getCred('password'))!;
  setState(() {});
}

@override
void initState() {
  super.initState();
  sharedPreference().checkValuePresent('email');
  sharedPreference().checkValuePresent('password');
  getData();
  print('Email: $email\nPassword $password');
  print('inside initstate');
  try {
    firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
  } on FirebaseAuthException catch (errMsg) {
    if (errMsg.code == 'user-not-found' ||
        errMsg.code == 'wrong-password' ||
        errMsg.code == 'Email format is not valid') {
      print('inside if: $errMsg');
      sharedPreference().reset();
      Timer(const Duration(seconds: 3), () {
        /*Move to Login*/
      });
    } else {
       /*Move to HomeScreen*/
    }
  }
}

This is the code for sharedPreference().getCred

Future<String?> getCred(String email) async {
  try {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    final result = prefs.getString('email');
    return result;
  } catch (e) {
    return 'Error Fetching Data';
  }
}

Here is the code of whole sharedPreference Class

import 'package:shared_preferences/shared_preferences.dart';

class sharedPreference {
  sharedPrefInit() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
  }

  checkValuePresent(key) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool CheckValue = prefs.containsKey('$key');
    print('printing from: (bool)$CheckValue');
  }

  saveCred({required String email, required String password}) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString('email', email);
    prefs.setString('password', password);
  }

  Future<String?> getCred(String email) async {
    try {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      final result = prefs.getString('email');
      return result;
    } catch (e) {
      return 'Error Fetching Data';
    }
  }

  reset() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.remove('email');
    prefs.remove('password');
  }
}

Secondly When I run the app I can't see my sharedpreference folder in the file explorer. I don't know that I have to create it? If yes the How? I initialize the sharedPreference in the main function.

Here is the code:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  await sharedPreference().sharedPrefInit();

  runApp(MaterialApp(
      theme: ThemeData(
        primarySwatch: mycolor,
        fontFamily: 'Raleway',
      ),
      debugShowCheckedModeBanner: false,
      initialRoute: 'AppSplashScreen',
      routes: {
        'AppSplashScreen': (context) => const AppSplashScreen(),
      }));
}

Solution

  • Please name classes with capital case e.g. SharedPreference and use ! operator only if you are sure that the value you get is non-nullable, otherwise use null aware operators:

    Future<void> getData() async {
      email = (await sharedPreference().getCred('email')) ?? '';
      password = (await sharedPreference().getCred('password')) ?? '';
    }
    

    In initState() firebaseAuth.signInWithEmailAndPassword() is called before asynchronous function getData() is executed, so put it inside getData() as well:

    Future<void> getData() async {
      email = (await sharedPreference().getCred('email')) ?? '';
      password = (await sharedPreference().getCred('password')) ?? '';
    
      print('Email: $email\nPassword $password');
      print('inside initstate');
      try {
        firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
      } on FirebaseAuthException catch (errMsg) {
        if (errMsg.code == 'user-not-found' ||
            errMsg.code == 'wrong-password' ||
            errMsg.code == 'Email format is not valid') {
          print('inside if: $errMsg');
          sharedPreference().reset();
          Timer(const Duration(seconds: 3), () {
            /*Move to Login*/
          });
        } else {
           /*Move to HomeScreen*/
        }
      }
    
    }
    
    @override
    void initState() {
      super.initState();
      sharedPreference().checkValuePresent('email');
      sharedPreference().checkValuePresent('password');
      getData();
    }