如何在streambuilder中执行异步调用?

时间:2020-07-08 14:54:35

标签: flutter google-cloud-firestore firebase-authentication

我有一个Flutter应用,该应用使用FirebaseAuth进行身份验证,并使用Firestore存储数据。为了存储用户个人资料(姓名,照片等),我在Firestore数据库中创建了一个单独的集合。

因此,一旦用户注册,他就会被重定向到一个屏幕,可以在其中添加其个人资料数据。再次将这些数据存储为文档。

我想在应用启动时实施相同的检查: 因此,我显示了一个启动屏幕,并在后端对其进行了检查,

  1. 用户是否登录?如果是,请继续,否则将他重定向到“条款和条件”页面。
  2. 该馆藏有用户个人资料吗?如果是,请继续,否则将他重定向到可以添加照片等的页面。

我能够完成第1点,但是我无法进行第二次检查。

这是代码:

class SplashScreen extends StatelessWidget {
  static final String id = 'splash_screen';
  final Firestore _firestore = Firestore.instance;

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<FirebaseUser>(
      stream: FirebaseAuth.instance.onAuthStateChanged,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.active) {
          FirebaseUser user = snapshot.data;
          if (user == null) {
            return TermsAndConditions();
          }
          // Check if user profile has been created
          return ChatsScreen();
        } else {
          return SplashScreenContent();
        }
      },
    );
  }
}

带注释的行是检查用户个人资料的代码所在的位置。 我尝试了以下方法:

_firestore.collection('users').where('id', isEqualTo: user.uid).snapshots().first.then( (value) {
            if(value.documents.isEmpty) {
              return ProfileScreen();
            }
    });

据我了解,我无法从回调将值返回给外部函数。我该如何实现

1 个答案:

答案 0 :(得分:1)

您要做的是每次都显示启动画面。

然后,在初始屏幕内,您可以创建支票。

initState内调用此函数

  void bootstrap() async {
    var user = await FirebaseAuth.instance.currentUser();
    if (user == null) {
      Navigator.push(context,
          MaterialPageRoute(builder: (context) => TermsAndConditions()));
      return;
    }
    DocumentSnapshot userDoc =
        await Firestore.instance.collection("users").document(user.uid).get();
    if (!userDoc.exists) {
      Navigator.push(
          context, MaterialPageRoute(builder: (context) => ProfilePage()));
      return;
    }
    Navigator.push(
        context, MaterialPageRoute(builder: (context) => ChatsScreen()));
  }

您还可以添加最初的2-3秒延迟,否则启动屏幕可能会突然更改。

您可以在pub.dev中找到许多启动屏幕库,这些库可让您执行此引导程序。