How to update boolean value in Firestore from a switch tile?

767

You could improve your updateNotifications() function to not have duplicate code:

 Future<void> updateNotifications() async {

     await FirebaseFirestore.instance
          .collection('userNotifications')
          .doc(currentSignedInUserID)
          .update({
        'messages': notificationsActive,
     });
    
    setState(() {
     notificationsActive = !notificationsActive;
    });
  }

And also I would suggest to you to listen to your Firestore collection and update UI on change. You can look up on how to do that here.

Share:
767
Carleton Y
Author by

Carleton Y

Updated on January 03, 2023

Comments

  • Carleton Y
    Carleton Y over 1 year

    My goal is to have a userNotifications collection in Firestore that is used to track user notification preferences. The user can toggle between true and false based on tapping a switch tile. With the code below, Firestore is immediately and correctly updating the boolean value based on user interaction and the user interface is updating and reflecting the changes. If the user logs out and logs back in, the boolean value is accurately reflected in the user interface.

    Before I apply this approach more broadly in the code I was hoping that someone can comment and let me know if my approach to updating the boolean value in Firestore is valid or point me in a better direction so I can improve my code. Links to SO posts or documentation are fine as I am more than willing to read and learn. Thanks in advance for any help.

    class NotificationsMessagesTile extends StatefulWidget {
    
      const NotificationsMessagesTile({
        Key? key,
      }) : super(key: key);
    
      @override
      State<NotificationsMessagesTile> createState() =>
          _NotificationsMessagesTileState();
    }
    
    class _NotificationsMessagesTileState extends State<NotificationsMessagesTile> {
      bool notificationsActive = false;
      final String? currentSignedInUserID = Auth().currentUser?.uid;
    
      Future<void> updateNotifications() async {
        if (!notificationsActive) {
          notificationsActive = true;
          FirebaseFirestore.instance
              .collection('userNotifications')
              .doc(currentSignedInUserID)
              .update({
            'messages': false,
          });
        } else {
          notificationsActive = false;
          FirebaseFirestore.instance
              .collection('userNotifications')
              .doc(currentSignedInUserID)
              .update({
            'messages': true,
          });
        }
        setState(() {});
      }
    
      @override
      Widget build(BuildContext context) {
        return SwitchListTileSliver(
          icon: Provider.of<NotificationsPageProvider>(context).areMessagesTurnedOn
              ? Icons.notifications_active
              : Icons.notifications_off,
          onChanged: (bool value) {
            final provider = Provider.of<NotificationsPageProvider>(
              context,
              listen: false,
            );
            provider.updateMessagesSettings(isOn: value);
            updateNotifications();
          },
          subTitle:
          Provider.of<NotificationsPageProvider>(context).areMessagesTurnedOn
              ? const Text(
            SettingsPageString.messagesOn,
          )
              : const Text(
            SettingsPageString.messagesOff,
          ),
          title: SettingsPageString.messages,
          value:
          Provider.of<NotificationsPageProvider>(context).areMessagesTurnedOn,
        );
      }
    }
    
  • Carleton Y
    Carleton Y over 2 years
    thanks very much for improving my code and providing the link. I actually don't fully understand why yet but your code works perfectly so I will review the link and learn about 'listening' in my Firestore collection.
  • Hrvoje Čukman
    Hrvoje Čukman over 2 years
    You are welcom!