Using async methods in initState() flutter

I am using firebase and need to get the id of the user inside my initState() method as I am building a widget that requires the id of the user, from firebase. The currentUser method that firebase uses is a Future.

Currently, I have this as my init state and getUser function:

Future<FirebaseUser> getUser() async {
    FirebaseUser user = await FirebaseAuth.instance.currentUser();
    return user;
  }

void initState() {
    getUser().then((result) {
      stream = Firestore.instance.collection('Lessons').where("teacher", isEqualTo: result.uid).limit(4).snapshots();

      _AppBarOptions = <Widget>[
        AppBar(
          title: new Text('Dashboard', style: TextStyle(color: Colors.white)),
          backgroundColor: Colors.white,
        ),
        AppBar(
            title: new Text('Lessons', style: TextStyle(color: Colors.white))),
        AppBar(title: new Text('Tasks', style: TextStyle(color: Colors.white))),
        AppBar(
            title: new Text('Settings', style: TextStyle(color: Colors.white)))
      ];

      _widgetOptions = <Widget>[
        Text(
          'Dashboard will go here',
          style: optionStyle,
        ),
        StreamBuilder(
            stream: stream,
            builder: (context, snapshot) {
              if(snapshot.hasData) {
                return ListView.builder(
                  itemExtent: 80.0,
                  itemCount: snapshot.data.documents.length,
                  itemBuilder: (context, index) =>
                      _buildListItem(context, snapshot.data.documents[index]),
                );
              } else {
                return Text('You have no Lessons');
              }

            }),
        Text(
          'Tasks will go here',
          style: optionStyle,
        ),
        Container(
          child: new RaisedButton(
            child: new Text('Sign Out'),
            onPressed: signOut,
          ),
        )
      ];
    });
  }

The problem that I am facing is that the build method is executed before this finishes, which uses the widgetOptions to display the text, resulting in an error.

I was wondering if there was any way to improve this as to be able to get the id of the user and use it in stream so that it can fetch the documents?

Thanks very much in advance.

Upvotes: 2

Views: 5680

Answers (2)

To mitigate this problem, you can use a boolean and setState() to change its value. Once you have the id of the user, then you can build the widget that needs the user id if the boolean is true, and otherwise make the widget a progress indicator or simply "loading" text.

Upvotes: 0

Alexander Arendar
Alexander Arendar

Reputation: 3425

For such cases Flutter has FutureBuilder widget.

It "postpones" building of a UI piece to the moment when the provided Future completes.

Read the API docs of this class, view some examples and you will resolve your problem.

As a result you will unload the part of your initState method where you construct the list of options to the builder argument of the FutureBuilder.

Upvotes: 5

Related Questions