【发布时间】:2020-11-06 00:23:59
【问题描述】:
在我的应用程序中,我聆听来自 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,这会弄乱我应用程序中的一些组件。
有没有更好的解决方法?
【问题讨论】:
标签: firebase flutter dart firebase-authentication flutter-provider