Little Monkey
Little Monkey

Reputation: 6157

Flutter: inherited widget

I want to do a login app. I have a class user, which has an id and a username that I want to keep to display it later in the app, and I have a user_api class, where I do the http request. I wanted to use Singleton to store the user once the user logins in, but I find out that inherited widget was a better idea. So now I'm struggling with them because I can't store the user object. After I login, my user becomes null and I can't figure out how it works. Here's my code: basically we have a root page that manages the cases in which the user is logged in or not:

void main() {
  runApp(MyApp());

 class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Model(
      user: User(),
      child: MaterialApp(
        routes: {
          '/login': (context) => new LoginView(),
          '/homepage_view': (context) => new HomepageView(),
        },
        title: 'Flutter login demo',
        home: RootPage(),
      ),
    );
  }
}

In the rootPage:

enum UserStatus {
  notDetermined,
  notSignedIn,
  signedIn,
}

class RootPage extends StatefulWidget {
  @override
  _RootPageState createState() => _RootPageState();
}

class _RootPageState extends State<RootPage> {

  UserStatus userStatus = UserStatus.notDetermined;

  @override
  void didChangeDependencies() {
    // TODO: implement didChangeDependencies
    super.didChangeDependencies();
    var user = Model.of(context).user;
    setState(() {
      userStatus = user.id == null? UserStatus.notSignedIn : UserStatus.signedIn;
      print((userStatus));
    });
  }

  void _signedIn() {
    setState(() {
      userStatus = UserStatus.signedIn;
    });
  }

  void _signedOut() {
    setState(() {
      userStatus = UserStatus.notSignedIn;
    });
  }

  @override
  Widget build(BuildContext context) {

    switch (userStatus) {
      case UserStatus.notDetermined:
        return _buildWaitingScreen();
      case UserStatus.notSignedIn:
        return LoginView(
          onSignedIn: _signedIn,
        );
      case UserStatus.signedIn:
        return HomepageView(
          onSignedOut: _signedOut,
        );
    }
    return Container(
      child: Text(("CHILD")),
    );
  }
}


Widget _buildWaitingScreen() {
  return Scaffold(
    body: Container(
      alignment: Alignment.center,
      child: CircularProgressIndicator(),
    ),
  );
}

the most important stuff of the login page::

var user = Model.of(context).user;
 user = await getUserByIdClient()
if (user.loginError == false){
        print (user);
        widget.onSignedIn();
}

Here's my inherited widget:

class Model extends InheritedWidget {
  Model({Key key, Widget child, this.user}) : super(key: key, child: child);
  final User user;

  @override
  bool updateShouldNotify(InheritedWidget oldWidget) => true;

  static Model of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(Model) as Model);
  }
}

Upvotes: 1

Views: 1089

Answers (1)

Omatt
Omatt

Reputation: 10463

From what I understand, it seems that you're looking in to storing user session in your app. One way of doing this is by storing user credentials in shared_preferences (i.e. userId). Depending on your use case, your backend might require users to re-authenticate, so keep an eye on that.

Store user credentials after login.

// Obtain shared preferences.
final prefs = await SharedPreferences.getInstance();

// Save user details on userId
String userId = ...;
await prefs.setString('userId', userId);

When has been signed out, you can remove the data.

await prefs.remove('userId');

For verifying user session, you can then check the stored value. If it's empty, logout the user.

final String? userId = prefs.getString('userId');

if(userId != null){
  // User is logged-in
} else {
  // User is signed-out
}

Upvotes: 0

Related Questions