Flutter 提供者消费者未在 NotifyListeners() 上进行更新

问题描述 投票:0回答:1

我正在开发一个 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 似乎具有陈旧的值。

flutter firebase
1个回答
0
投票

修好了!你的建议让我检查了我在哪里调用它。进行此更改:

// await AuthenticationProvider().verified(true); 
await context.read<AuthenticationProvider>().verified(true); 

解决了这个问题。不太清楚为什么,但确实如此。谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.