firebase - 颤动的firebase注销失败
问题描述
状态管理太难了。
通过firebase登录正常工作,第一次注销工作正常。
但是,如果您登录并转到另一个屏幕,则无法注销。
什么地方出了错?
- 注销提供程序
'''
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,
),
)
),
如果我像下面这样修改它,它工作正常。但我不知道这是否是正确的方法。
'''
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))),
),
'''
提供者
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(); }); }
}
包装器'''
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(); }
}
'''
解决方案
使用.then
然后导航到包装器并没有错,但您可能希望将onPressed
代码重构为:
onPressed: () async {
await loginProvider.logout();
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (BuildContext context) => Wrapper())
);
},
由于您正在使用async/await
,因此仅使用它而不是将其与.then
.
推荐阅读
- javascript - 顺序回调的javascript练习
- javascript - 秘银组件如何在这里工作是我的一些奇怪的经历
- kotlin - Tornadofx:在 runAsync 任务期间更新标签文本 (FXML)
- sql - 使用实体框架迁移转换 SQL 列的类型
- highcharts - 如何避免 Webdatarocks 过滤器功能以避免在图表和数据透视表中链接过滤器
- lets-encrypt - 如何让 Traefik 信任我们公司的 CA 来生成 letencrypt 证书?
- javascript - 如何借助 RecordRTC 在 JavaScript 中创建 WAV 流?
- postgresql - 如何从 postgres 分组集查询中删除空值
- node.js - mongoose find() 文档具有大小 > 0 的属性数组
- google-chrome - Zalenium:禁用 chrome 中的下载弹出窗口