title: Flutter - Looking up a deactivated widget's ancestor is unsafe with Provider package, FireStore authentication
body: <p>I have an problem with showing message via SnackBar using Provider package. The error message I get is:</p>
  
  <pre><code>VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
  At this point the state of the widget's element tree is no longer stable.
  To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
  #0      Element._debugCheckStateIsActiveForAncestorLookup.&lt;anonymous closure&gt; (package:flutter/src/widgets/framework.dart:3508:9)
  #1      Element._debugCheckStateIsActiveForAncestorLookup (package:flutter/src/widgets/framework.dart:3522:6)
  #2      Element.findAncestorStateOfType (package:flutter/src/widgets/framework.dart:3641:12)
  #3      Scaffold.of (package:flutter/src/material/scaffold.dart:1313:42)
  #4      LoginScreen.build.&lt;anonymous closure&gt;.&lt;anonymous closure&gt; (package:zvjs_app/screens/login_screen.dart:74:38)
  &lt;asynchronous suspension&gt;
  #5      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182&lt;…&gt;
  </code></pre>
  
  <p>Bellow is my code, I think all classes that are part of logic that is needed. I can't understand why Future isn't "available" or what error means in user_log_in_provider.dart in sigIn method. I also tried to show errorMessage from sigIn method via variable _errorMessage which you can see in user_log_in_provider.dart and then check if this message isn't null. In this way code runs but it is showing one message delayed. For e. first login failed(wrong email format) -> no message shown. Second login failed(wrong password) -> message with wrong email format is shown.</p>
  
  <p>main.dart</p>
  
  <pre><code>void main() =&gt; runApp(MyApp());
  
  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MultiProvider(
        providers: [
          ChangeNotifierProvider(create: (_) =&gt; UserLogIn.instance()),
          ChangeNotifierProvider.value(value: Accommodations()),
        ],
        child: MaterialApp(
          title: 'ZVJS',
          theme: ThemeData(
              primarySwatch: Colors.blue,
              buttonTheme: ButtonThemeData(
                buttonColor: Colors.blue[300],
                padding: EdgeInsets.symmetric(
                  vertical: 8.0,
                  horizontal: 16.0,
                ),
              )),
          home: MyHomePage(),
          routes: {
            RegistrationScreen.routeName: (context) =&gt; RegistrationScreen(),
            MainScreen.routeName: (context) =&gt; MainScreen(),
            LoginScreen.routeName: (context) =&gt; MyHomePage(),
          },
        ),
      );
    }
  }
  
  class MyHomePage extends StatelessWidget {
    final _emailController = TextEditingController();
    final _passwordController = TextEditingController();
  
    @override
    Widget build(BuildContext context) {
      return Consumer&lt;UserLogIn&gt;(
        builder: (context, user, _) {
          switch (user.status) {
            case Status.Uninitialized:
  //            return Splash();
            case Status.Unauthenticated:
            case Status.Authenticating:
              return LoginScreen(
                  emailController: _emailController,
                  passwordController: _passwordController);
            case Status.Authenticated:
              return MainScreen();
            default:
              return ErrorPage();
          }
        },
      );
    }
  }
  </code></pre>
  
  <p>login_screen.dart</p>
  
  <pre><code>class LoginScreen extends StatelessWidget {
    static const routeName = '/loginScreen';
  
    final _emailController;
    final _passwordController;
  
    LoginScreen(
        {@required TextEditingController emailController,
        @required TextEditingController passwordController})
        : this._emailController = emailController,
          this._passwordController = passwordController;
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text(Constants.logInPageTitle),
        ),
        body: Provider.of&lt;UserLogIn&gt;(context).status == Status.Authenticating
            ? SpinnerCustom(Constants.loggingIn)
            : Center(
                child: SingleChildScrollView(
                  child: Column(
                    children: &lt;Widget&gt;[
                      Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 8.0),
                        child: TextFieldCustom(
                          text: Constants.email,
                          controller: _emailController,
                          icon: Icon(Icons.email),
                          textInputType: TextInputType.emailAddress,
                        ),
                      ),
                      const SizedBox(height: 20),
                      Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 8.0),
                        child: TextFieldCustom(
                          text: Constants.password,
                          controller: _passwordController,
                          icon: Icon(Icons.lock),
                          textInputType: TextInputType.visiblePassword,
                        ),
                      ),
                      const SizedBox(height: 10),
                      Builder(
                        builder: (ctx) =&gt; ButtonCustom(
                          text: Constants.logIn,
                          onPressed: () async {
                            var provider = Provider.of&lt;UserLogIn&gt;(ctx, listen: false);
                            String message = await provider.signIn(
                                  _emailController.text,
                                  _passwordController.text);
                            if (message != null) {
                              Scaffold.of(ctx).showSnackBar(SnackBar(
                                content: Text(message),
                              ));
                            }
                          },
                        ),
                      ),
                    ],
                  ),
                ),
              ),
      );
    }
  }
  </code></pre>
  
  <p>user_log_in_provider.dart</p>
  
  <pre><code>enum Status { Uninitialized, Authenticated, Authenticating, Unauthenticated }
  
  class UserLogIn with ChangeNotifier {
    FirebaseAuth _auth;
    FirebaseUser _user;
    Status _status = Status.Uninitialized;
    String _errorMessage;
  
    UserLogIn.instance() : _auth = FirebaseAuth.instance {
      _auth.onAuthStateChanged.listen(_onAuthStateChanged);
    }
  
    Status get status =&gt; _status;
  
    FirebaseUser get user =&gt; _user;
  
    String get errorMessage =&gt; _errorMessage;
  
    Future&lt;String&gt; signIn(String email, String password) async {
      try {
        _status = Status.Authenticating;
        notifyListeners();
        await _auth.signInWithEmailAndPassword(email: email, password: password);
        return null;
      } catch (e) {
        _errorMessage = e.message;
        print(_errorMessage);
        _status = Status.Unauthenticated;
        notifyListeners();
        return e.message;
      }
    }
  
    Future&lt;void&gt; _onAuthStateChanged(FirebaseUser firebaseUser) async {
      if (firebaseUser == null) {
        _status = Status.Unauthenticated;
      } else {
        _user = firebaseUser;
        _status = Status.Authenticated;
      }
      notifyListeners();
    }
  }
  </code></pre>