1

ive been having probem with pulling data out from firebase, currently it keeps returning me Instance of 'Future<String?>' instead of a String of "Patient" or "Physiotherapist", may i know what's the issue?

class Wrapper extends StatefulWidget {

  @override
  _WrapperState createState() => _WrapperState();
}

class _WrapperState extends State<Wrapper> {
  Future<String?> getUserType(String uid) async {
    try {
      DocumentSnapshot _docSnapShot = await FirebaseFirestore.instance.collection('users').doc(uid).get();
      var userType = await ( _docSnapShot.data() as dynamic)['userType'];
      print(userType);
      return await userType;
    } catch (e) {
      print(e);
    }
  }


  @override
  Widget build(BuildContext context) {
    final user = Provider.of<CustomUser?>(context);

    //return either Home or Authenticate widget
    if ( user == null) {
      print("this");
      return Authenticate();
    } else if (getUserType(user.uid) == "Patient") {
      print('this happens');
      return PatientHome();
    } else {
      print(getUserType(user.uid).toString() + "this thing");
      return PhysioHome();
    }
  }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Roy Chua
  • 23
  • 4
  • Is your question based on the value of the print statement? – Rohan Thacker Jun 08 '21 at 18:22
  • Does this answer your question? [What is a Future and how do I use it?](https://stackoverflow.com/questions/63017280/what-is-a-future-and-how-do-i-use-it) – Christopher Moore Jun 08 '21 at 18:23
  • @RohanThacker , yes my apologies for not being clearer : my question is based off by getUserType(user.id) , i want to return a String but it ends up returning a Future instead. – Roy Chua Jun 08 '21 at 18:40
  • Is the correct value printed on the console? – Rohan Thacker Jun 08 '21 at 18:44
  • @RohanThacker , When it reaches the else if statement, getUserType(user.uid) is evaluated as a Future instead of a String. The correct value from print(usertype) in my getUsertype method only returns after the evaluation by the build method. – Roy Chua Jun 08 '21 at 18:51
  • I recommend checking out some of these results: https://www.google.com/search?q=site%3Astackoverflow.com+%5Bgoogle-cloud-firestore%5D%5Bflutter%5D+Instance+of+Future%3CString%3F%3E+instead+of+String – Frank van Puffelen Jun 08 '21 at 19:09

1 Answers1

1

As the return value of getUserType() is a Future<String?> you either need to access the value in a .then() callback or you need to await the Future value in an async function.

Since you are using the function in a Flutter Widget the build method you wont be able to use an async function as the build method should be a synchronous function. However you can use a FutureBuilder for this use case.

Update your build method to use a Future Builder like the example code below:

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<CustomUser?>(context);
    if (user == null) {
     return Authenticate();
    } else {
    return FutureBuilder(
      future: getUserType(user.uid),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          final userType = snapshot.data;
          if (userType == 'Patient') {
            return PatientHome();
          } else {
            return PhysioHome();
          }
        } else {
            // A Widget to show while the value loads
            return Text('Loading'); 
        }
      }
    );
   }
  }

Also See:

Flutter Widget of the Week - FutureBuilder

FutureBuilder Docs

Rohan Thacker
  • 5,377
  • 3
  • 21
  • 34
  • @RoyChua If this answer helped you, consider marking it as the accepted answer, so we can help others with the same question. – Rohan Thacker Jun 14 '21 at 15:20