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.