Reputation: 6157
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
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