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

时间:2020-06-01 14:08:38

标签: flutter google-cloud-firestore async-await

我想基于一个名为isAdmin的布尔变量来决定在屏幕上显示什么内容。该字段的值是从firestore中获取的。

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

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());
  }

问题在于,无论isAdmin的值如何,我总是被路由到PatientPage()。我怀疑这是由于没有等待isUserAnAdmin()返回的值而发生的。我以为我可以等待isUserAnAdmin(),但是不能在脚手架的主体中使用await。

我认为可以通过以下方法解决此问题:

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

但是我收到一条错误消息:

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

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

3 个答案:

答案 0 :(得分:2)

您的身体应该使用FutureBuilder:

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

要使用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(),
            );
          }
        }
);
  }