Carleton Y
Carleton Y

Reputation: 309

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

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,
    );
  }
}

Upvotes: 1

Views: 1744

Answers (1)

Hrvoje Čukman
Hrvoje Čukman

Reputation: 447

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.

Upvotes: 2

Related Questions