I am trying to implement login/logout in Flutter using this example. Log in works fine and the console output is:
flutter: LOGIN WIDGET BUILD CONTEXT:
flutter: LoginScreen(dirty, state: LoginScreenState#552db)
flutter: _ctx:
flutter: LoginScreen(state: LoginScreenState#552db)
But after logging out, I can't log back in (the context is lost). After logging out and then trying to log back in, the context within onAuthStateChanged()
is lost after logout:
flutter: LOGIN WIDGET BUILD CONTEXT:
flutter: LoginScreen(dirty, state: LoginScreenState#d112e)
flutter: _ctx
flutter: LoginScreen
login.dart
class LoginScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new LoginScreenState();
}
}
class LoginScreenState extends State<LoginScreen>
BuildContext _ctx;
@override
onAuthStateChanged(AuthState state) {
print("_ctx");
print(_ctx.toString());
if(state == AuthState.LOGGED_IN) {
print("ready to login");
Navigator.of(_ctx).pushReplacementNamed("/home");
}
}
@override
Widget build(BuildContext context) {
_ctx = context;
print("LOGIN WIDGET BUILD CONTEXT:");
print(_ctx.toString());
}
}
home.dart
class Settings extends StatelessWidget {
@override
Widget build(BuildContext context) => new Container(
child: new ListView(
children: <Widget>[
new ListTile(
//leading: Icon(Icons.map),
title: new Text('About')
),
new ListTile(
//leading: Icon(Icons.photo_album),
title: new Text('Logout'),
onTap: () {
Navigator.of(context).pushReplacementNamed("/login");
}
)
],
),
);
The routes:
final routes = {
'/login': (BuildContext context) => new LoginScreen(),
'/home': (BuildContext context) => new Tabs(),
'/' : (BuildContext context) => new LoginScreen(),
};
Wy isn't _ctx
updated in onAuthStateChanged()
and is there a better way to handle login state?
You are reusing an old BuildContext
instance. Don't save the instance in the build
method. You should never ever do this.
Your LoginScreen
is a StatefulWidget
and it's state (LoginScreenState
) already has context
property. Try using this instead.
You also need to dispose the listener, the example already has a dispose(AuthListener)
method that you can use.
@override
void dispose() {
super.dispose(); // always call super for dispose/initState
AuthStateProvider().dispose(this);
}
In general the example is pretty old and I would suggest finding a more recent tutorial. Flutter and Dart is evolving very fast and a 2 year old example is not the way to go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With