How to update BottomNavigationBar Widget when receiving notifications

Viewed 16

I'm fairly new to flutter and am having trouble getting my BottomNavigationBar to update when my app receives a notification (eg. a new message in the users inbox). I've tried a couple solutions, like adding a listener in the 'initState' function, but it seems to cause a memory leak issue. Here is my basic structure of the app in pseudo code:

main.dart


import 'globals.dart' as globals;

  @override
  void initState() {
  addListeners();
  super.initState();
  }

void addListeners() {
  FirebaseMessaging.onMessage.listen((RemoteMessage event) {

    switch (event.data["type"]) {
            case 'message':
              debugPrint("New messages received");
              globals.myInbox.value = data["messageCount"];
              break;
          }
    }
}

... [All routes defined here] ...

layout.dart

import 'globals.dart' as globals;

class StandardLayout extends StatefulWidget {
    Widget InboxCount() {
        int messageCount = globals.myInbox;
    }


@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          backgroundColor: Colors.blue,
        ),
        body: Container(
          height: double.infinity,
          width: double.infinity,
          color: Colors.white60,
          child: widget.output,

        ),
        bottomNavigationBar:
          BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
               ... [Other config options] ..
            items: [
              BottomNavigationBarItem(
                label: 'Home',
                icon: Icon(Icons.home),
              ),
              BottomNavigationBarItem(
                label: 'Schedule',
                icon: Icon(Icons.calendar_today),
              ),
              BottomNavigationBarItem(
                label: 'Time Off',
                icon: Icon(Icons.beach_access),
              ),
              BottomNavigationBarItem(
                label: 'Messages',
                icon: Stack(
                  children: [
                    Icon(Icons.messenger),
                    InboxCount() //Stacks the badge on this item

                  ],
                )
              )
            ],
          )
    );
  }
}

example.dart

import 'layout.dart';

class ExampleScreen extends StatelessWidget {
  const ExmapleScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
   return StandardLayout('title': 'Example Screen', 'output': Container(child: Text('Hello World!')));
  }
}

Attempt #1:

If I add a listener to the layout.dart like so:

 @override
  void initState() {
      globals.myInbox.addListener(() {
        //Refresh the layout
        debugPrint('Reloading Layout');
        setState(() {});
    });
    super.initState();
  }

it sort of works, but it fires mutliple times as I can see the debugPrint message being displayed 2,3,4,5 even upto 6 times. I will also sometimes get messages saying the state is unreachable, been disposed, or warnings about memory leaks. So obviously it is getting fired too many times. Attempt #2

If I add the listener to the main.dart file, the listener event only gets fired once when the globals.myInbox value changes, so thats good! Unfortunately, the bottom navigation in layout.dart doesn't get updated obviously because I can't send a 'setState' to another file. So now what?

Is my structure of a dart/flutter program completely wrong that it won't allow me to do what I want? Where do I put the listener or how do I implement it so the bottom navigation will update when "globals.myInbox" gets updated?

Hopefully that makes sense, I omitted a bunch of code that isn't relevant to the problem.

0 Answers
Related