title: show snackbar on fcm notification on every screen
body: <p>I want to show snackbar when in app notification arrive.
  But  when I configure firebase on first screen, snackbar shows only when user is on that screen.
  I try to create a class to get BuildContext and show snackbar based on it but doesn't work and not show snackbar.</p>
  
  <p><br />
  This is my HomeScreen.dart:</p>
  
  <pre><code>class _HomeScreenState extends State&lt;HomeScreen&gt; {
    @override
    void initState() {
      super.initState();
      Future.delayed(Duration.zero, () {
        NotificationManger.init(context: context);
        Fcm.initConfigure();
      });
    }
  
    @override
    Widget build(BuildContext context) {
      return StoreConnector&lt;AppState, Store&lt;AppState&gt;&gt;(
        converter: (store) =&gt; store,
        onInit: (store) =&gt; initApp(store),
        builder: (context, store) {
          return BlocProvider&lt;HomeBloc&gt;(
            create: (context) {
              return HomeBloc(homeRepository: homeRepository)..add(ScreenOpened());
            },
            child: BlocListener&lt;HomeBloc, HomeState&gt;(
              listener: (context, state) async {},
              child: BlocBuilder&lt;HomeBloc, HomeState&gt;(
                builder: (context, state) {
                  return Scaffold(
                    key: _scaffoldKey,
                    ...
                  );
                },
              ),
            ),
          );
        },
      );
    }
  }
  </code></pre>
  
  <p>This is my Fcm.dart</p>
  
  <pre><code>Future&lt;dynamic&gt; myBackgroundMessageHandler(Map&lt;String, dynamic&gt; message) {
    if (message.containsKey('data')) {
      final dynamic data = message['data'];
    }
    if (message.containsKey('notification')) {
      final dynamic notification = message['notification'];
    }
  }
  
  class Fcm {
    static final FirebaseRepository repository = FirebaseRepository();
    static final FirebaseMessaging _fcm = FirebaseMessaging();
  
    static initConfigure() {
      if (Platform.isIOS) _iosPermission();
  
      _fcm.requestNotificationPermissions();
      _fcm.autoInitEnabled();
  
      _fcm.configure(
        onMessage: (Map&lt;String, dynamic&gt; message) async =&gt; NotificationManger.onMessage(message),
        onLaunch: (Map&lt;String, dynamic&gt; message) async =&gt; NotificationManger.onLaunch(message),
        onResume: (Map&lt;String, dynamic&gt; message) async =&gt; NotificationManger.onResume(message),
        onBackgroundMessage: myBackgroundMessageHandler,
      );
  
      _fcm.getToken().then((String token) {
        print('token: $token');
        repository.setUserNotifToken(token);
      });
    }
  
    static _iosPermission() {
      _fcm.requestNotificationPermissions(IosNotificationSettings(sound: true, badge: true, alert: true));
      _fcm.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
        print("Settings registered: $settings");
      });
    }
  }
  </code></pre>
  
  <p>and this is my NotificationManager.dart:</p>
  
  <pre><code>class NotificationManger {
    static BuildContext _context;
  
    static init({@required BuildContext context}) {
      _context = context;
    }
  
    static onMessage(Map&lt;String, dynamic&gt; message) {
      print(message);
      _showSnackbar(data: message);
    }
  
    static onLaunch(Map&lt;String, dynamic&gt; message) {
      print(message);
    }
  
    static onResume(Map&lt;String, dynamic&gt; message) {
      print(message);
    }
  
    static _showSnackbar({@required Map&lt;String, dynamic&gt; data}) {
      // showDialog(context: _context, builder: (_) =&gt; );
      SnackBar snackBar = SnackBar(
        content: Text(
          data['data']['title'],
          style: TextStyle(
            fontFamily: 'Vazir',
            fontSize: 16.0,
          ),
        ),
        backgroundColor: ColorPalette.primary,
        behavior: SnackBarBehavior.floating,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(45.0),
        ),
        elevation: 3.0,
      );
      Scaffold.of(_context).showSnackBar(snackBar);
    }
  }
  </code></pre>
  
  <p><code>main.dart</code></p>
  
  <pre><code>class App extends StatelessWidget {
    final Store&lt;AppState&gt; store;
    App(this.store);
    @override
    Widget build(BuildContext context) {
      return StoreProvider(
        store: store,
        child: MaterialApp(
          ...
        ),
      );
    }
  }
  </code></pre>
  
  <p>I am using redux and bloc, so any approach with these tools is ok for me.</p>
  
  <p>This is my sample screen:</p>
  
  <pre><code>
  class Reminders extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: appBar,
        body: Center(
          child: Text('reminders'),
        ),
      );
    }
  }
  </code></pre>
  
  <p><strong>SOLUTION</strong>:
  Add <code>NotificationManger.init(globalKey: _scaffoldKey);</code> to all screens solve the problem.</p>
  
  <pre><code>class Reminders extends StatelessWidget {
    final GlobalKey&lt;ScaffoldState&gt; _scaffoldKey = GlobalKey&lt;ScaffoldState&gt;();
  
    @override
    Widget build(BuildContext context) {
      NotificationManger.init(globalKey: _scaffoldKey);
  
      return Scaffold(
        key: _scaffoldKey,
        appBar: appBar,
        body: Center(
          child: Text('reminders'),
        ),
      );
    }
  }
  
  </code></pre>
  
  <p><strong>SOLUTION 2</strong></p>
  
  <p>Using<em>Get</em> library to using only one function and no need to add it in all screen: <a href="https://pub.dev/packages/get" rel="nofollow noreferrer">https://pub.dev/packages/get</a></p>