title: Flutter - How to pass user data to all views
body: <p>I'm new to the flutter world and mobile app development and struggling with how I should pass user data throughout my app.</p>
  <p>I've tried several things, but none seem great and I'm sure there are best practice patterns I should be following.</p>
  <p>Because it makes examples easier, I'm using firebase for authentication.
  I currently have a separate route for logging in. Once I'm logged in I want the User model in most views for checking permissions on what to show, displaying user info in the drawer, etc...</p>
  <p>Firebase has an <code>await firebaseAuth.currentUser();</code> Is it best practice to call this everywhere you might need the user? and if so, where is the best spot to place this call?</p>
  <p>The <a href="https://codelabs.developers.google.com/codelabs/flutter-firebase/" rel="noreferrer">flutter codelab</a> shows a great example of authenticating users before allowing writes. However, if the page needs to check auth to determine what to build, the async call can't go in the <code>build</code> method.</p>
  <h2>initState</h2>
  <p>One method I've tried is to override initState and kick off the call to get the user. When the future completes I call <code>setState</code> and update the user.</p>
  <pre><code>    FirebaseUser user;
  
      @override
      void initState() {
        super.initState();
        _getUserDetail();
      }
  
    Future&lt;Null&gt; _getUserDetail() async {
      User currentUser = await firebaseAuth.currentUser();
      setState(() =&gt; user = currentUser);
    }
  </code></pre>
  <p>This works decent but seems like a lot of ceremony for each widget that needs it. There is also a flash when the screen loads without the user and then gets updated with the user upon the future's completion.</p>
  <h2>Pass the user through the constructor</h2>
  <p>This works too but is a lot of boilerplate to pass the user through all routes, views, and states that might need to access them. Also, we can't just do <code>popAndPushNamed</code> when transitioning routes because we can't pass a variable to it. We have to change routes similar to this:</p>
  <pre><code>Navigator.push(context, new MaterialPageRoute(
      builder: (BuildContext context) =&gt; new MyPage(user),
  ));
  </code></pre>
  <h2>Inherited Widgets</h2>
  <p><a href="https://medium.com/@mehmetf_71205/inheriting-widgets-b7ac56dbbeb1" rel="noreferrer">https://medium.com/@mehmetf_71205/inheriting-widgets-b7ac56dbbeb1</a></p>
  <p>This article showed a nice pattern for using <code>InheritedWidget</code>.  When I place the inherited widget at the MaterialApp level, the children aren't updating when the auth state changed (I'm sure I'm doing it wrong)</p>
  <pre><code>  FirebaseUser user;
  
    Future&lt;Null&gt; didChangeDependency() async {
      super.didChangeDependencies();
      User currentUser = await firebaseAuth.currentUser();
      setState(() =&gt; user = currentUser);
    }
  
    @override
    Widget build(BuildContext context) {
      return new UserContext(
        user,
        child: new MaterialApp(
          title: 'TC Stream',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new LoginView(title: 'TC Stream Login', analytics: analytics),
          routes: routes,
        ),
      );
    }
  </code></pre>
  <h2>FutureBuilder</h2>
  <p>FutureBuilder also seems like a decent option but seems to be a lot of work for each route. In the partial example below, <code>_authenticateUser()</code> is getting the user and setting state upon completion.</p>
  <pre><code>  @override
    Widget build(BuildContext context) {
      return new FutureBuilder&lt;FirebaseUser&gt;(
        future: _authenticateUser(),
        builder: (BuildContext context, AsyncSnapshot&lt;FirebaseUser&gt; snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return _buildProgressIndicator();
          }
          if (snapshot.connectionState == ConnectionState.done) {
            return _buildPage();
          }
        },
      );
    }
  </code></pre>
  <p>I'd appreciate any advice on best practice patterns or links to resources to use for examples.</p>