How to close Functions in ChangeNotifier Provider Flutter

Issue

How to close a Function without disposing it. I needy this answer because when I log out, I need to close the functions in ChangeNotifier Class.

This Is my ChangeNotifier Class:

class ChatAndRequestProvider extends ChangeNotifier {
  bool _areThereNewChatsAndRequests = false;
  bool get areThereNewChatsAndRequests => _areThereNewChatsAndRequests;
  set areThereNewChatsAndRequests(bool value) {
    _areThereNewChatsAndRequests = value;
    notifyListeners();
  }

  List _chatsList = [];
  List get chatsList => _chatsList;

  set chatsList(List list) {
    _chatsList = list;
    notifyListeners();
  }

  getChats() async {
    var prefs = await SharedPreferences.getInstance();
    print('The getChats Id is ${prefs.getString(kUserId)}');
    FirebaseDatabase.instance
        .reference()
        .child('users')
        .child(prefs.getString(kUserId))
        .child('friendsArray')
        .onValue
        .listen((snapshot) {
      Map list = snapshot.snapshot.value;
      print('map is $list');
      var newItems = [];
      if (list != null) {
        list.forEach((key, value) {
          newItems.add(value);
        });
        chatsList = newItems;
        var globalArray = [];
        for (var item in newItems) {
          if (item[kLastTimestamp] != item[kLastTimestampSeen]) {
            areThereNewChatsAndRequests = true;
          }
          var status;
          switch (item['friendsStatus']) {
            case 'friends':
              status = RequestStatus.alreadyAFriend;
              break;
            case 'notFriends':
              status = RequestStatus.noRequest;
              break;
            case 'blocked':
              status = RequestStatus.userThatBlockedMe;
              break;
            case 'unblocked':
              status = RequestStatus.noRequest;
              break;
          }
          globalArray.add({kUserId: item[kUserId], kTypeOfRequest: status});
        }
        valuesList = globalArray;
      } else {
        deleteFromList(null, RequestStatus.alreadyAFriend);
        chatsList = [
          {kUserId: 'null'}
        ];
      }
    });
  }

So for example when I log In as user1 and I call this function in the LoadingScreen() I get all of users that are my friends, and I can go to the chats screen List and chat with my friends. Up to this point there is no issue. But when I log out and when I log in with another account lets say user2 and I call this function again, then I get error and two responses because I am calling this function twice. I am not using Auth Packet, I have my own database on MongoDB where I store user Info, but requests and chats are stored on RealTime Database.
So my Question is:
When user1 logs out of my app, I can not call dispose() on provider because if he wants to log in again to another account, he will get an error because Provider was disposed, so how can I stop listening to my database when user logs out and call this function again. Thank You very Much!!

Solution

I´m not sure if this works because I don’t fully understand the flow of your app but you say that

I can not call dispose() on provider because if he wants to log in
again to another account,

when the users logs out shouldn’t the app return to the first screen disposing the provider? (unless you create it in the MaterialApp, I’m not sure about that either). You could save the instance of the Firebase listener and then close it when you log out/ dispose the provider

var _myListener;

getChats() async {
    var prefs = await SharedPreferences.getInstance();
    print('The getChats Id is ${prefs.getString(kUserId)}');
    _myListener = FirebaseDatabase.instance
        .reference()
        .child('users')
        .child(prefs.getString(kUserId))
        .child('friendsArray')
        .onValue
        .listen((snapshot) ...
        ....
        /// The rest of your code
}

void closeListener(){ //call it when the user logs out
   _myListener?.close();
}

@override
void dispose(){
  closeListener(); // or call it in the dispose if you want 
                   //to dispose and create a new provider when the user logs out/ sign in
  super.dispose();
}

Answered By – EdwynZN

Answer Checked By – Mary Flores (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.