如果 Firestore 上的用户文档已更改,则更新提供者中的用户数据

Update user data in provider if user document has changed on firestore

如果 Firestore 上的用户文档已更改,我想更新提供商中的用户数据。

实际上,我使用提供程序将当前用户数据存储在一个名为_currentUser 的变量中。此变量有助于在多个屏幕上显示用户数据。

class UserService extends ChangeNotifier {
  final CollectionReference usersCollection =
      FirebaseFirestore.instance.collection('users');
  late User _currentUser;
  User get currentUser => _currentUser;

  Future<User> getUser(String uid) async {
    var userData = await usersCollection.doc(uid).get();
    User user = User.fromMap(userData.data()!);
    _currentUser = user;
    print("nb lives : ${_currentUser.nbLives}");
    notifyListeners();
    return user;
  }
}

当前用户数据会随时间变化,我当前解决方案的问题是,如果用户文档发生变化,_currentUser 变量不会更新,旧数据会显示在应用程序屏幕上。我想找到一种方法来收听此文档并在用户数据更改时更新 _currentUser 变量。

我找到的一个解决方案是使用 Streams 来获取用户数据,但我不喜欢它,因为它在特定屏幕上运行,而不是在后台运行。

有没有人遇到过类似的问题?感谢您的帮助!

您可以通过多种方式做到这一点

  1. 当您在 firestore 中更新 _currentUser 时,在 provider 变量中使用 notifylistner 更新相同的内容,并将使用 _currentUser 的小部件包装在 Consumer 中,所以更改总是得到更新。

  2. 在您的根小部件中,将 StreamBuilder 与流一起使用:....snapshots() 并根据更改更新 _currentUser

这取决于您的用例,并希望事物对 _currentUser 的更改做出反应。

class UserService extends ChangeNotifier {
  final CollectionReference usersCollection =
      FirebaseFirestore.instance.collection('users');
  late User _currentUser;
  User get currentUser => _currentUser;

  void init(String uid) async {
    // call init after login or on splash page (only once) and the value
    // of _currentUser should always be updated.
    // whenever you need _currentUser, just call the getter currentUser.
    usersCollection.doc(uid).snapshots().listen((event) {
      _currentUser = User.fromMap(event.data()!);
      notifyListeners();
    });
  }
}