如何关闭 ChangeNotifier Provider Flutter 中的函数
How to close Functions in ChangeNotifier Provider Flutter
如何在不处理函数的情况下关闭它。我需要这个答案,因为当我注销时,我需要关闭 ChangeNotifier Class.
中的功能
这是我的 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'}
];
}
});
}
因此,例如,当我以 user1 身份登录并在 LoadingScreen() 中调用此函数时,我得到了所有是我朋友的用户,我可以转到聊天屏幕列表并与我的朋友聊天。到目前为止没有问题。但是,当我注销并使用另一个帐户登录时,让我们说 user2 并再次调用此函数,然后我收到错误消息和两个响应,因为我调用了此函数两次。我没有使用 Auth Packet,我在 MongoDB 上有自己的数据库,我在其中存储用户信息,但请求和聊天存储在实时数据库中。
所以我的问题是:
当 user1 注销我的应用程序时,我无法在提供者上调用 dispose() 因为如果他想再次登录到另一个帐户,他会因为提供者被处置而收到错误消息,所以当用户时我如何停止收听我的数据库注销并再次调用此函数。非常感谢!!
我不确定这是否有效,因为我不完全了解您应用的流程,但您这么说
I can not call dispose() on provider because if he wants to log in
again to another account,
当用户注销时,应用程序 return 不应该在第一个屏幕上配置提供商吗? (除非你在 MaterialApp 中创建它,否则我也不确定)。您可以保存 Firebase 侦听器的实例,然后在注销/处置提供者时将其关闭
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();
}
如何在不处理函数的情况下关闭它。我需要这个答案,因为当我注销时,我需要关闭 ChangeNotifier Class.
中的功能这是我的 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'}
];
}
});
}
因此,例如,当我以 user1 身份登录并在 LoadingScreen() 中调用此函数时,我得到了所有是我朋友的用户,我可以转到聊天屏幕列表并与我的朋友聊天。到目前为止没有问题。但是,当我注销并使用另一个帐户登录时,让我们说 user2 并再次调用此函数,然后我收到错误消息和两个响应,因为我调用了此函数两次。我没有使用 Auth Packet,我在 MongoDB 上有自己的数据库,我在其中存储用户信息,但请求和聊天存储在实时数据库中。 所以我的问题是: 当 user1 注销我的应用程序时,我无法在提供者上调用 dispose() 因为如果他想再次登录到另一个帐户,他会因为提供者被处置而收到错误消息,所以当用户时我如何停止收听我的数据库注销并再次调用此函数。非常感谢!!
我不确定这是否有效,因为我不完全了解您应用的流程,但您这么说
I can not call dispose() on provider because if he wants to log in again to another account,
当用户注销时,应用程序 return 不应该在第一个屏幕上配置提供商吗? (除非你在 MaterialApp 中创建它,否则我也不确定)。您可以保存 Firebase 侦听器的实例,然后在注销/处置提供者时将其关闭
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();
}