1

I'm trying to build my first mobile application with flutter and firebase.

  • Error: The argument type 'Future Function()' can't be assigned to the parameter type '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']);
             });
       }
     }
    
lenz
  • 2,193
  • 17
  • 31
  • 1
    I recommend you take some time to read up on [dart asynchronous programming](https://dart.dev/codelabs/async-await). It will save you a lot of headaches in the future. No pun intended – lenz Aug 22 '20 at 10:43

1 Answers1

1

For the first part of your code, consider something like this:

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

That should solve that error (hence answering your question). Although the rest of the code will still fail. You should read up on futures and async programming.


Now my suggested solution for the whole thing.
Since you have 2 different async sources that create your stream, you might want to consider creating your own Stream! (Yes, streams are powerful like that).

In sequence, you’re wanting to

  • await on the future: .currentUser()
  • use the result of that to create your firestore snapshot stream

Try something like this

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']);
         });
   }
 }
lenz
  • 2,193
  • 17
  • 31