【发布时间】:2020-11-04 02:31:05
【问题描述】:
我一直在尝试使用从我的身份验证Provider 获得的 uid 创建流到 Firestore 文档:
class AuthService {
...
static final provider = StreamProvider.autoDispose((ref) => FirebaseAuth.instance.onAuthStateChanged);
...
}
但是,我很难根据来自身份验证 Provider 的值实际创建一个 StreamProvider。
class User {
...
static final provider = StreamProvider((ref) {
final stream = ref.read(AuthService.provider);
// Returns AsyncValue<Stream<User>> instead of desired AsyncValue<User>
return stream.map((auth) => Service.user.stream(auth.uid));
});
...
}
我还尝试使用 Computed 返回 uid 或流本身,但您无法从 Provider 读取 Computed(回想起来这很有意义)。
This question 与此主题最相关,但它处理的是 Provider,而不是 Riverpod。
附:可以创建 Riverpod 标签吗?
编辑:
答案并不完全正确。 await for loop 只会触发一次,而侦听器会捕获所有事件。
static final provider = StreamProvider((ref) async* {
final stream = ref.read(AuthService.provider);
print('userProvider init');
stream.listen((auth) {
print('LISTENED: ${auth?.uid}');
});
await for (final auth in stream) {
print('uid: ${auth?.uid}');
yield* Service.user.stream(auth?.uid);
}
});
此代码在登录时产生以下内容:
userProvider init
LISTENED: <redacted UID>
uid: <redacted UID>
然后退出:
LISTENED: null
我也希望看到uid: null,这将更新流,但在任何更多的身份验证事件中,只有侦听器被触发,await for loop 不会捕获任何事件。
有趣的是,使用颤振检查器,身份验证提供者发出的值也永远不会改变:
AutoDisposeStreamProvider<FirebaseUser>#95f11: AsyncValue<FirebaseUser>.data(value: FirebaseUser(Instance of 'PlatformUser'))
通过登录/注销事件持续存在,这可以解释这种行为,但我不确定如何修复它。
有什么想法吗?我已经被这个问题困扰了一段时间,无法纠正这个问题。
【问题讨论】:
-
我已将语法更新为 0.6.0-dev
-
@RémiRousselet 太棒了,谢谢!我一直在关注您在 Riverpod 上的工作,很高兴看到我的问题将得到解决。一旦 0.6.0 发布,我将接受您的回答,我可以测试更改。
-
Riverpod 文档说不要在 Provider 构造函数中使用“ref.read(”...但我看到 Remi 已经审查了这个问题并且没有反对你的代码。我有一个github 上的未决问题寻求澄清这一点。
-
@Dewey 这个问题是在更改为使用 ref.watch 之前出现的。所以,你是对的。