Rafael
Rafael

Reputation: 1

How to update, in real time, a value in the main screen, updated in another page using Hive in Flutter?

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

Answers (1)

Firas AT
Firas AT

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

Related Questions