Как использовать Future в StreamBuilder во Flutter

Я пытаюсь создать свое первое мобильное приложение с 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']);
             });
       }
     }
    

person Community    schedule 22.08.2020    source источник
comment
Я рекомендую вам потратить некоторое время на то, чтобы ознакомиться с асинхронным программированием dart. Это избавит вас от многих головных болей в будущем. Никакой каламбур   -  person lenz    schedule 22.08.2020


Ответы (1)


Для первой части вашего кода рассмотрите что-то вроде этого:

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

Это должно решить эту ошибку (следовательно, отвечая на ваш вопрос). Хотя остальной код все равно выйдет из строя. Вам следует ознакомиться с фьючерсами и асинхронным программированием.


Теперь предлагаемое мной решение для всего этого.
Поскольку у вас есть 2 разных асинхронных источника, которые создают ваш поток, вы можете подумать о создании своего собственного Stream! (Да, потоки такие мощные).

Последовательно вы хотите

  • ждать в будущем: .currentUser ()
  • используйте результат этого для создания потока моментальных снимков хранилища огня.

Попробуйте что-то вроде этого

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']);
         });
   }
 }
person lenz    schedule 22.08.2020