如何在Flutter中的StreamBuilder中使用Future

问题描述

我正在尝试使用Flutter和firebase构建我的第一个移动应用程序。

  • 错误: 无法将参数类型'Future Function()'分配给参数类型'String'

     class ShowUserData extends StatefulWidget {
       @override
       _ShowUserDataState createState() => _ShowUserDataState();
     }
    
     class _ShowUserDataState extends State<ShowUserData> {
    
       final email = () {
         final userEmail =
             FirebaseAuth.instance.currentUser().then((user) => user.email);
         print('userEmail + $userEmail');
         return userEmail;
       };
    
       @override
       Widget build(BuildContext context) {
         return StreamBuilder(
             // stream: user.getUserData().asstream(),stream: Firestore.instance.collection('users').document(email).snapshots(),builder: (context,snapshot) {
               if (!snapshot.hasData) {
                 return Text("Loading");
               }
    
               print('snapshot + $snapshot');
               var userDocument = snapshot.data;
               print('userDocument + $userDocument');
               return Text(userDocument['firstName']);
             });
       }
     }
    
  • @H_404_11@

    解决方法

    对于代码的第一部分,请考虑以下内容:

       Future<String> getUserEmail() async {
         final userEmail =
             FirebaseUser user = await FirebaseAuth.instance.currentUser();
         String userEmail = user.email;
         print('userEmail + $userEmail');
         return userEmail;
       };
    

    那应该可以解决该错误(因此可以回答您的问题)。尽管其余代码仍将失败。您应该阅读futures and async programming


    现在,我建议了整个解决方案。
    由于您有2个不同的异步源来创建流,因此您可能要考虑创建自己的流! (是的,流是如此强大)。

    依次,您要

    • 等待未来:.currentUser()
    • 使用该结果创建您的Firestore快照流

    尝试这样的事情

    class ShowUserData extends StatefulWidget {
       @override
       _ShowUserDataState createState() => _ShowUserDataState();
     }
    
     class _ShowUserDataState extends State<ShowUserData> {
    
       Stream currentUserStream() async* {
         FirebaseUser user = await FirebaseAuth.instance.currentUser();
         String userEmail = user.email;
         yield* Firestore.instance.collection('users').document(userEmail).snapshots();     
       };
    
       @override
       Widget build(BuildContext context) {
         return StreamBuilder(
             // stream: user.getUserData().asStream(),stream: currentUserStream(),builder: (context,snapshot) {
               if (!snapshot.hasData) {
                 return Text("Loading");
               }
    
               print('snapshot + $snapshot');
               var userDocument = snapshot.data;
               print('userDocument + $userDocument');
               return Text(userDocument['firstName']);
             });
       }
     }