我正在开发一个 flutter 应用程序,使用 firestore 作为我的数据库和状态管理提供者。这个想法基本上是,我仅在某些情况下从 firestore 获取数据(例如要显示的用户名),然后使用 flutter 安全存储将其存储在本地。然后,我使用提供程序来处理此问题并在某些情况下获取新数据。我现在遇到一个问题,尽管安全存储已更新,但提供程序实例似乎保留了一些陈旧的数据,并且我无法更改它。这是通过运行 flutter restart 来解决的,但显然这不是我想要的。 这是提供者:
class UserData {
final String uid;
final String name;
final String profilePictureUrl;
final bool verified;
UserData(
{required this.uid,
required this.name,
required this.verified,
required this.profilePictureUrl});
Map<String, dynamic> toJson() => {
'uid': uid,
'name': name,
'profilePictureUrl': profilePictureUrl,
'verified': verified,
};
factory UserData.fromJson(Map<String, dynamic> json) {
return UserData(
uid: json['uid'],
name: json['name'],
profilePictureUrl: json['profilePictureUrl'],
verified: json['verified'],
);
}
}
class AuthenticationProvider with ChangeNotifier {
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
UserData? _userData;
AuthenticationProvider() {
_auth.authStateChanges().listen(_onAuthStateChanged);
}
UserData? get userData => _userData;
Stream<User?> get authStateChanges => _auth.authStateChanges();
Future<void> verified(bool verified) async {
User? user = _auth.currentUser;
if (user != null) {
await _firestore.collection('users').doc(user.uid).update({
'verified': verified,
});
_userData = await _getUserData(user.uid);
await _cacheUserData(_userData!);
notifyListeners();
}
}
Future<UserData> _getUserData(String uid) async {
DocumentSnapshot doc = await _firestore.collection('users').doc(uid).get();
if (doc.exists) {
return UserData(
uid: uid,
name: doc['name'],
profilePictureUrl: (doc.data() as Map<String, dynamic>?)
?.containsKey('profilePictureUrl') ??
false
? doc['profilePictureUrl']
: '',
verified: doc['verified']);
} else {
throw Exception('Document does not exist');
}
}
Future<void> _cacheUserData(UserData userData) async {
String userDataJson = jsonEncode(userData.toJson());
await _secureStorage.write(key: 'user_data', value: userDataJson);
}
Future<UserData?> getCachedUserData() async {
String? userDataJson = await _secureStorage.read(key: 'user_data');
if (userDataJson != null) {
Map<String, dynamic> userDataMap = jsonDecode(userDataJson);
return UserData.fromJson(userDataMap);
}
return null;
}
Future<void> _clearCachedUserData() async {
await _secureStorage.delete(key: 'user_data');
}
void _onAuthStateChanged(User? user) async {
if (user == null) {
_userData = null;
await _clearCachedUserData();
} else {
_userData = await _getUserData(user.uid);
await _cacheUserData(_userData!);
}
notifyListeners();
}
问题与验证有关(布尔验证)。当我呼唤它时, 首先正确更新了,安全存储也正确更新了,但是当消费者访问时 _userData 似乎已经过时,如下所示:
Widget TopOfPage(BuildContext context, double screenHeight) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Consumer<AuthenticationProvider>(
builder: (context, authenticationProvider, _) {
if (authenticationProvider.userData != null) {
print("user is authenticated");
// User is authenticated, retrieve their first name from Firestore
if (authenticationProvider.userData!.verified) {
return ProfileShowcase(
context, screenHeight, authenticationProvider);
} else {
请注意,当有:
if (Provider.of<AuthenticationProvider>(context,
listen: false)
.userData!
.verified
问题是一样的。
有人知道如何解决这个问题吗?我很茫然,已经尝试了一切感觉。谢谢!
尝试了很多调试打印,它们都支持我所说的,_userData 似乎具有陈旧的值。
修好了!你的建议让我检查了我在哪里调用它。进行此更改:
// await AuthenticationProvider().verified(true);
await context.read<AuthenticationProvider>().verified(true);
解决了这个问题。不太清楚为什么,但确实如此。谢谢!