Firebase StreamProvider侦听用户不';当用户更改时,无法更新

Firebase StreamProvider侦听用户不';当用户更改时,无法更新,firebase,flutter,dart,firebase-authentication,flutter-provider,Firebase,Flutter,Dart,Firebase Authentication,Flutter Provider,在我的应用程序中,我监听云Firestore中用户文档的更改。 我通过获取当前用户ID,然后获取与该ID关联的文档来实现这一点 class UserService { ... //GET A USER'S INFORMATION AS A STREAM // ? IF NO UID IS PASSED, IT GETS THE INFO OF THE CURRENT USER Stream<User> getUserInfoAsStream({String uid

在我的应用程序中,我监听云Firestore中用户文档的更改。 我通过获取当前用户ID,然后获取与该ID关联的文档来实现这一点

class UserService {
  ...

  //GET A USER'S INFORMATION AS A STREAM
  // ? IF NO UID IS PASSED, IT GETS THE INFO OF THE CURRENT USER

  Stream<User> getUserInfoAsStream({String uid}) async* {
    if (uid == null) {
      uid = await AuthService().getUID();
    }

    yield* Firestore.instance
        .collection('users')
        .document(uid)
        .snapshots()
        .map((doc) => User.fromFirestore(doc));
  }

  ...
在应用程序的生命周期中,它可以完美地工作,但是当用户使用
FirebaseAuth.instance.signOut()注销时
然后与其他用户登录,流保持不变(即它侦听旧的uid流),而StreamProvider不侦听新的数据流

|注销代码以供参考|

// ? SIGN OUT CODE: If user signed out, it returns true, else, false
  Future<bool> signOut() async {
    try {
      await _firebaseAuth.signOut();
      return true;
    } catch (error) {
      print(error);
      return false;
    }
  }
FlatButton(
   onPressed: () {
     AuthService().signOut().then((value) =>
       Navigator.of(context).pushAndRemoveUntil(
           CupertinoPageRoute(
              builder: (BuildContext context) {
                   return Onboarding();
             }), (route) => false));
          },
     child: Text("Yes")),
为了解决这个问题,我应该将当前uid传递给StreamProvider,但是我只能异步获取当前uid

如何使用StreamProvider侦听异步流,并在用户更改时更新它

编辑:我通过在登录页面之后立即将提供者向上移动到窗口小部件树的屏幕上,在一定程度上解决了这个问题。但由于提供者的范围是有限的,我不得不在我原来的MaterialApp之后创建一个全新的MaterialApp,这会弄乱我应用程序中的一些组件


有更好的解决方法吗?

我通过从
提供程序
包切换到
获取它
解决了这个问题

get_it
允许您注册和注销singleton,这意味着当用户登录时,我可以注册singleton,以便在依赖它的所有屏幕上使用它。然后,当我注销时,我只是注销它。这样,用户总是在登录和注销后更新

下面是你自己怎么做的

在您的pubspec.yaml中安装软件包
get\u it

get_it: ^4.0.2
main.dart
旁边创建一个名为
locator.dart
的新文件。在其中添加以下代码:

GetIt locator = GetIt.instance;

void setupLocator() {
  // Replace this with the object you're trying to listen to.
  User user;
  Stream<User> userStream = UserService().getUserInfoAsStream();
  userStream.listen((event) => user = event);
  locator.registerLazySingleton(() => user); // Register your object
}
locator.unregister<User>();
这就是我所做的一切,让它运行起来

编辑:我使用
UserProvider
Singleton监听身份验证中的更改,然后在用户登录时获取当前用户,从而使它变得更好、更轻

import 'package:planster/models/core/user.dart';
import 'package:planster/models/services/auth_service.dart';
import 'package:planster/models/services/user_service.dart';

class UserProvider {
  // SINGLETON INITIALIZATION
  static final UserProvider _singleton = UserProvider._internal();

  factory UserProvider.instance() {
    return _singleton;
  }
  UserProvider._internal() {
    listenToUserAuthState();
  }

  // VARIABLES
  User user;

  void listenToUserAuthState() async {
    AuthService().onAuthStateChanged.listen((event) {
      uid = event.uid;
      if (uid != null)
        UserService().getUserInfoAsStream(uid: uid).listen((userEvent) {
          user = userEvent;
        });
    });
  }
}
import 'package:planster/models/core/user.dart';
import 'package:planster/models/services/auth_service.dart';
import 'package:planster/models/services/user_service.dart';

class UserProvider {
  // SINGLETON INITIALIZATION
  static final UserProvider _singleton = UserProvider._internal();

  factory UserProvider.instance() {
    return _singleton;
  }
  UserProvider._internal() {
    listenToUserAuthState();
  }

  // VARIABLES
  User user;

  void listenToUserAuthState() async {
    AuthService().onAuthStateChanged.listen((event) {
      uid = event.uid;
      if (uid != null)
        UserService().getUserInfoAsStream(uid: uid).listen((userEvent) {
          user = userEvent;
        });
    });
  }
}