gpt4 book ai didi

firebase - 用户更改时,StreamProvider监听用户的消息不会更新

转载 作者:行者123 更新时间:2023-12-03 03:51:50 26 4
gpt4 key购买 nike

在我的应用程序中,我收听Cloud 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));
}

...
然后,我使用 StreamProvider收听我的 main.dart中的流
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
StreamProvider<User>.value(
value: UserService().getUserInfoAsStream(),
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: SplashScreen(),
),
);
}
}
在应用程序的生命周期中,它可以正常运行,但是当用户使用 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,这使我的应用程序中的某些组件困惑了。
有更好的解决方法吗?

最佳答案

我设法从provider包切换到get_it来解决此问题。get_it允许您注册和注销单例,这意味着当用户登录时,我可以注册单例,以便可以在依赖它的所有屏幕上使用它。然后,当我注销时,我只是注销了它。这样,用户始终在登录和注销后进行更新。
这是您自己的操作方法。
在pubspec.yaml中安装get_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
}
登录时,只需调用 setupLocator();,然后注销即可,请使用以下代码:
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;
});
});
}
}

关于firebase - 用户更改时,StreamProvider监听用户的消息不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62932908/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com