Reputation:
state management is too difficult.
Login through firebase works normally and logout works well the first time.
However, if you log in and go to another screen, you cannot log out.
What went wrong?
'''
Future logout() async {
await firebaseAuth.signOut();
}
'''
'''
Widget build(BuildContext context) {
final loginProvider = Provider.of<AuthProvider>(context);
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
onPressed: () async => await loginProvider.logout(),
icon: Icon(
Icons.settings,
color: Colors.white,
),
)
),
If I modify it like below, it works fine. But I don't know if it's the right way.
'''
onPressed: () async => await loginProvider.logout().then(
(value) => Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (BuildContext context) => Wrapper()))),
'''
Future login(String email, String password) async {
setLoading(true);
try {
UserCredential authResult = await firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
User? user = authResult.user;
setLoading(false);
return user;
} on SocketException {
setMessage('No internet');
} catch (e) {
setLoading(false);
setMessage(e.toString());
}
notifyListeners();
}
'''
'''
'''
Container(
height: 50.0,
margin: EdgeInsets.only(top: 20.0),
width: MediaQuery.of(context).size.width * 0.8,
child: MaterialButton(
color: Color(0xffe50815),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
onPressed: () async {
if (this._formKey.currentState!.validate()) {
print('email : ${this.idCt.text}');
print('password : ${this.pwCt.text}');
await loginProvider.login(
this.idCt.text.trim(), this.pwCt.text.trim());
}
},
child: loginProvider.isLoading
? CircularProgressIndicator()
: Text("LOGIN",
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.bold,
color: Colors.white))),
),
'''
provider
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _init = Firebase.initializeApp();
return FutureBuilder(
future: _init,
builder: (BuildContext context, snapshot) {
if (snapshot.hasError) {
return Column(
children: [
Icon(Icons.error),
Center(
child: Text('something went wrong!'),
),
],
);
} else if (snapshot.hasData) {
return MultiProvider(
providers: [
ChangeNotifierProvider<AuthProvider>.value(
value: AuthProvider(),
),
StreamProvider<User?>.value(
value: AuthProvider().user,
initialData: null,
catchError: (_, err) => null,
),
ChangeNotifierProvider(
create: (BuildContext context) =>
MovieNowPlayingProvider()),
ChangeNotifierProvider(
create: (BuildContext context) => TvPopularProvider()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: SplashScreen(),
),
);
}
return Container();
});
}
}
Wrapper '''
class Wrapper extends StatelessWidget {
const Wrapper({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final user = Provider.of<User?>(context);
if (user != null) {
return MainScreen();
}
return Authentication();
}
}
'''
Upvotes: 0
Views: 139
Reputation: 7696
Using .then
and then navigating to the wrapper is not wrong but you might want to restructure the onPressed
code to this:
onPressed: () async {
await loginProvider.logout();
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (BuildContext context) => Wrapper())
);
},
Since you're using async/await
, it's more consistent to use just that instead of combining it with .then
.
Upvotes: 0