[英]Flutter Riverpod Firebase currentUser Provider not updated
[英]Flutter Riverpod and Firebase
我一直在研究一些使用 riverpod 的示例,试图正确地将逻辑与 UI 层和业务层分开。 在这种情况下,我的用例是我想在 Firestore 中存储自定义用户配置文件,但是当涉及 ViewModel 时,我对提供程序设置感到困惑。
来自codewithandrea.com
的示例为每个屏幕定义了两个文件,一个 model (ProfileModel) 和一个页面/页面构建器 (ProfilePageBuilder)。 在 ProfilePageBuilder 的顶部,它声明了一个 state 提供程序来访问 ViewModel。 该提供程序解析 ProfileModel 所需的依赖项。
final profileModelProvider =
StateNotifierProvider.autoDispose<ProfileModel, ProfileState>((ref) {
final authService = ref.watch(authServiceProvider);
final databaseService = ref.watch(databaseProvider)!;
return ProfileModel(
authService: authService, databaseService: databaseService);
});
现在,我希望页面能够访问从 Firestore 返回的用户配置文件,但 Firestore 服务返回一个Stream<UserProfile>
。 我的问题是:
这是 Firebase 和 Riverpod 的常见问题。
是否要返回 stream 取决于您。 你不必。 这是决定你想要什么的思路。
我将使用带有代码生成语法的 riverpod 2.0,但如果您愿意,这些都可以在没有 codegen 的情况下编写,只是更冗长。
一种方法是使用来自package:rxdart
的 BehaviorSubject,它只记住 stream 的最后一个值。
import 'package:rxdart/rxdart.dart';
@riverpod
BehaviorSubject<UserProfile> userProfileSubject(
UserProfileStreamRef ref,
String userId,
/*more params if you want*/) {
final firebaseStream = ...
// goal of this provider is to get the stream
// from firebase and convert to a BehaviorSubject
return BehaviorSubject()
..addStream(firebaseStream);
}
@riverpod
UserProfile? userProfile(UserProfileRef ref) {
// this provider listens to the behavior subject
// and refreshes itself when the value changes
// so the dependent providers and widgets can react
final subject = ref.watch(userProfileSubjectProvider(userId, ...));
// if no params to provider
//final subject = ref.watch(userProfileSubjectProvider);
// when there's a new value, invalidate self
// so we re-run this and return the new value
subject.doOnData((newProfile) {ref.invalidateSelf();});
// note that subject can have a null value until
// first value is emitted from the stream or stream emits a null.
// your UI must handle this case.
return subject.value;
}
现在您的视图 model 或任何可以依赖于此userProfileProvider
或直接在ConsumerWidget
中使用它的视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.