Reputation: 1
I'm working with two screens (main screen and notifications screen). I'm receiving push notifications from Firebase, I have a class that receives this notification and adds Hive box 1(title, body, unread), I get the total number of notifications set as unread and update it in the other box 2(a record initialized with 0). On the main screen, I need to fetch the value of box 2 and update it in real time.
Basically when I receive a push notification, I'm adding the data for this new notification in a box(boxNotifications). Afterwards, I store the total number of notifications marked as unread in a variable. Then in the boxTotalNotifications box I update this value.
addNotifications(Box boxNotifications, title, body, boxTotalNotifications) async {
NotificationData newNotification = NotificationData(title: title, body: body, unread: true);
boxNotifications.add(newNotification);
var tNotifications = boxNotifications.values.where((item) => item.unread == true).toList().length;
boxTotalNotifications.putAt(0,tNotifications);
}
On the main screen, I define the totalNotificationsGet variable, then in the Widget build, I use setState to fetch the value in the TotalNotifications box. I display this value using a Text Widget. How do I get this value to be updated in real time.
var totalNotificationsGet;
@override
Widget build(BuildContext context) {
setState(() {
totalNotificationsGet = boxTotalNotifications.get(0);
});
return MaterialApp(
debugShowCheckedModeBanner: false,
home: DefaultTabController(
length: 4,
child: Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Center(
child: SingleChildScrollView(
child: Container(
constraints: BoxConstraints(
maxWidth: responsive.isTablet! ? width : width),
child: Center(
child: Column(
children: [
const SizedBox(height: 40),
Padding(
padding: responsive.isTablet!
? const EdgeInsets.fromLTRB(100, 0, 100, 0)
: const EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: responsive.isTablet! ? 110 : 85,
child: Image.asset('lib/images/liberty.png')),
GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: ((context) {
return const NotificationsPage();
})));
},
child: SizedBox(
//color: Colors.cyan,
width: 30,
height: 30,
child: Stack(
children: [
Icon(
Icons.notifications_outlined,
color: Colors.black,
size: responsive.isTablet! ? 40 : 30,
),
//totalNotifications.getCounter() >= 0
globals.count >= 0
? Container(
color: Colors.transparent,
width: 30,
height: 30,
alignment: Alignment.topRight,
margin: const EdgeInsets.only(
top: 5),
child: Container(
//color: Colors.green,
width: 15,
height: 15,
decoration: BoxDecoration(
shape: BoxShape.circle,
//color: Color(0xffc32c37),
color: Colors.red,
border: Border.all(
color: Colors.white,
width: 1)),
child: Padding(
padding:
const EdgeInsets.all(
0.0),
child: Center(
child: Text(
'$totalNotificationsGet',
Upvotes: 0
Views: 471
Reputation: 508
You don't need to use the setstate function like that. To dynamically update a widget based on changes made to a hive box, you can use a ValueListenableBuilder as so:
return ValueListenableBuilder(
//in your case, the key associated with data (total notifications) is 0
valueListenable:
Hive.box('your_box_name').listenable(keys: [key_associated_with_data]),
builder: (context, box, widget) {
final totalNotificationsGet = boxTotalNotifications.get(0);
return Center(
child: Text('$totalNotificationsGet'),
);
},
);
Upvotes: 0