我刚接触Flutter 世界和移动应用程序开发,正在为如何在我的应用程序中传递用户数据而苦苦挣扎.
我try 了几种方法,但没有一种看起来很好,我确信我应该遵循一些最佳实践模式.
因为它使示例更简单,所以我使用Firebase进行身份验证. 我目前有单独的登录路由.一旦我登录,我希望在大多数视图中的用户模型来判断权限,显示什么,在抽屉中显示用户信息,等等…
FireBase的值是await firebaseAuth.currentUser();
,在您可能需要用户的任何地方调用它是最佳实践吗?如果是这样的话,打这个电话的最佳地点是哪里?
flutter codelab显示了在允许写入之前对用户进行身份验证的一个很好的示例.但是,如果页面需要判断auth来确定要构建什么,则异步调用不能进入build
方法.
初始状态
我try 过的一种方法是重写初始状态并启动调用以获取用户.future 完成后,我会拨打setState
并更新用户.
FirebaseUser user;
@override
void 初始状态() {
super.初始状态();
_getUserDetail();
}
Future<Null> _getUserDetail() async {
User currentUser = await firebaseAuth.currentUser();
setState(() => user = currentUser);
}
这工作得不错,但对于每个需要它的小部件来说,似乎都有很多仪式.当屏幕在没有用户的情况下加载,然后在将来完成时与用户一起更新时,也会有一个闪光灯.
通过构造函数传递用户
这也是可行的,但要让用户通过可能需要访问它们的所有路由、视图和状态,这需要很多样板文件.此外,我们不能在转换路由时只执行popAndPushNamed
次,因为我们不能向它传递变量.我们必须改变类似的路由:
Navigator.push(context, new MaterialPageRoute(
builder: (BuildContext context) => new MyPage(user),
));
继承的小部件
https://medium.com/@mehmetf_71205/inheriting-widgets-b7ac56dbbeb1个
本文展示了使用InheritedWidget
的一个很好的模式.当我将继承的小部件放在MaterialApp级别时,当身份验证状态更改时,子部件不会更新(我确信我这样做是错误的)
FirebaseUser user;
Future<Null> didChangeDependency() async {
super.didChangeDependencies();
User currentUser = await firebaseAuth.currentUser();
setState(() => user = currentUser);
}
@override
Widget build(BuildContext context) {
return new UserContext(
user,
child: new MaterialApp(
title: 'TC Stream',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new LoginView(title: 'TC Stream Login', analytics: analytics),
routes: routes,
),
);
}
FutureBuilder
FutureBuilder似乎也是一个不错的 Select ,但每条路由似乎都有很多工作要做.在下面的部分示例中,_authenticateUser()
在完成时获取用户并设置状态.
@override
Widget build(BuildContext context) {
return new FutureBuilder<FirebaseUser>(
future: _authenticateUser(),
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return _buildProgressIndicator();
}
if (snapshot.connectionState == ConnectionState.done) {
return _buildPage();
}
},
);
}
如果有任何关于最佳实践模式的建议或示例资源的链接,我将不胜感激.