sermet
sermet

Reputation: 442

Flutter SharedPreferences getInstance return null

Although I set the _sharedPreferences in the constructor, it gets null in getUsername. I don't know missing what:

  class PreferencesProvider {
  SharedPreferences _sharedPreferences;

  PreferencesProvider() {
    SharedPreferences.getInstance().then((prefs) => _sharedPreferences = prefs);
  }

  String getUsername() {
    return _sharedPreferences.getString("Username");
  }

  String getX() {
    return _sharedPreferences.getString("X");
  }

  String getY() {
    return _sharedPreferences.getString("Y");
  }

  String getZ() {
    return _sharedPreferences.getString("Z");
  }
}

alternatively it didn't work either:

class LoginProvider {
  SharedPreferences _sharedPreferences;

  LoginProvider._internal();
  static final LoginProvider _instance = LoginProvider._internal();

  factory LoginProvider() {
    _instance.initPreferences();
    return _instance;
  }

  initPreferences() async {
    _sharedPreferences = await SharedPreferences.getInstance();
  }

I want to use this in MaterialApp:

initialRoute: PreferencesProvider().isLoggedIn() ? "MainPage" : "LoginPage"

Edit: I know I should use await. But then keyword isn't same? I don't want to wait the instance again for all returns. In the other hand, I can't use await in initialRoute.

Upvotes: 1

Views: 8266

Answers (3)

ibrahimkarahan
ibrahimkarahan

Reputation: 3017

You need to wait a little bit for get username from shared preferences. getInstance is an async process.

Below code will work, because getString will work after getInstance

Future<String> getUsername() async {
  _sharedPreferences = await SharedPreferences.getInstance();
  return _sharedPreferences.getString("Username");
}

You need to modify your PreferencesProvider class

Upvotes: 0

Jay Mungara
Jay Mungara

Reputation: 7150

The way i manage to login the user for my application for the similar scenario is,

String startPage="LoginPage";
void main() {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String user=prefs.getString("Username");
  if(user!=null && user.length>0){
    startPage="MainPage";
  }

  runApp(MyApp());
}

Now, set your initialRoute as follow,

initialRoute: startPage,

This solution works in every scenario because i am fetching the data before the runApp() function in my application. Your application renders your initialPage after calling the runApp() function.

This is the best way to manage your login page based on data retrieval from the sharedpreferences as SharedPreferences takes time to fetch the data. Till the data is retrieved from sharedpreferences your build method gets completed its UI rendering.

Upvotes: 2

Dharmesh Mansata
Dharmesh Mansata

Reputation: 4708

While using preferences you should use Future, await and async

Future<String> getUsername() async {

    SharedPreferences prefs = await SharedPreferences.getInstance();
    String storeUserDetails = prefs.getString("Username");
    return (storeUserDetails != null);
}

Hope this helps!

Upvotes: 0

Related Questions