在脚手架的主体中运行异步功能



我想根据一个名为isAdmin的布尔变量来决定屏幕中显示的内容。此字段的值是从火堆获取的。

这是我到目前为止得到的:

Future<bool> isUserAnAdmin() async {
var snap = await Firestore.instance
.collection("Users")
.document(UserSingleton().fireUser.uid)
.get();
UserSingleton().user = User.fromJson(snap.data);
return UserSingleton().user.isAdmin;
}
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
title: Text("hemlp"),
actions: [
Padding(
padding: const EdgeInsets.only(right: 15),
child: GestureDetector(
child: Icon(Icons.exit_to_app),
onTap: () async => await Auth.logoutUser().then(
(value) => Navigator.pushNamed(context, '/SignInPage')),
),
)
],
),
body: isUserAnAdmin() == true ? AdminPage() : PatientPage());
}

问题是我总是被路由到 PatientPage((,而不管 isAdmin 的值如何。我怀疑这种情况正在发生,因为它没有等待 isUserAnAdmin(( 返回的值。我以为我可以等待是UserAnAdmin((,但我不能在脚手架的主体中使用await。

我想我可以通过这样做来解决问题:

body: isUserAnAdmin().then((value) {
value == true ? AdminPage() : PatientPage(); 
})

但是我收到一个错误,指出:

The argument type 'Future<Null>' can't be assigned to the parameter type 'Widget'.

关于如何解决这个问题的任何想法?

你的身体应该使用一个 FutureBuilder:

body: FutureBuilder<bool>(
future: isUserAnAdmin(),
builder: (context, data) {
if (data.hasData && data.data) {
return AdminPage();
} else {
return PatientPage();
}
},
)

你应该在正文中使用 FutureBuilder。 这将调用您的异步函数并在结果准备就绪时更新。

为了使用Future,您需要使用 await。但通常在小部件中,我们使用 FutureBuilder 代替:

Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
title: Text("hemlp"),
actions: [
Padding(
padding: const EdgeInsets.only(right: 15),
child: GestureDetector(
child: Icon(Icons.exit_to_app),
onTap: () async => await Auth.logoutUser().then(
(value) => Navigator.pushNamed(context, '/SignInPage')),
),
)
],
),
body: FutureBuilder<bool>(
future: isUserAnAdmin(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (snapshot.hasData) {
if(snapshot.data == true) {
return AdminPage();
} else {
return PatientPage();
} else {
return Center(
child: CircularProgressIndicator(),
);
}
}
);
}