Flutter - Looking up a deactivated widget's ancestor is unsafe with Provider package, FireStore authentication Flutter - Looking up a deactivated widget's ancestor is unsafe with Provider package, FireStore authentication dart dart

Flutter - Looking up a deactivated widget's ancestor is unsafe with Provider package, FireStore authentication


Problem:

You are getting the error because of this code:

 Scaffold.of(ctx).showSnackBar(SnackBar(  content: Text(message), ));

The Scaffold.of(context) is attempting to look up the scaffold in a widget tree that is no longer above it.

Here is how the issue is arising:

  1. The login call is fired off asynchronously: String message = await provider.signIn(...);
  2. While the call is being awaited, the parents of the button widget may have changed, or the button itself may have been removed from the tree.
  3. Then, when Scaffold.of(ctx).showSnackbar(...) is called, it is now attempting to look up a scaffold in a widget tree that doesn't exist.

Solution:

There are a few solutions. One of them is to use a global scaffold which wraps each of your routes. That scaffold key can then be used to show snackbars.

Here is how that could be done:

Add a scaffold to your MaterialApp builder. Make sure to use the global key.

final globalScaffoldKey = GlobalKey<ScaffoldState>();class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MultiProvider(      ...      child: MaterialApp(       builder: (context, child) {        return Scaffold(          key: globalScaffoldKey,          body: child,        );      },...

You could then use that key to show snackbars through a global function:

 void showSnackbar(String message) {    var currentScaffold = globalScaffoldKey.currentState;    currentScaffold.hideCurrentSnackBar(); // If there is a snackbar visible, hide it before the new one is shown.    currentScaffold.showSnackBar(SnackBar(content: Text(message)));  }

Usage would look like this, and you can safely call it from anywhere in your code:

showSnackbar('My Snackbar Message')