I have been attempting to create streams to Firestore documents using the uid obtained from my auth Provider:
class AuthService {
...
static final provider = StreamProvider.autoDispose((ref) => FirebaseAuth.instance.onAuthStateChanged);
...
}
However, I am struggling to actually create a StreamProvider dependent on the value from the auth Provider.
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));
});
...
}
I also tried using Computed to return the uid or the stream itself but you cannot read a Computed from a Provider (which makes sense in retrospect).
This question is the most relevant on this topic but it is dealing with Provider, not Riverpod.
P.S. Can a Riverpod tag be created?
Edit:
The answer isn't working quite right. The await for loop is only ever triggering once, whereas a listener catches all events.
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);
}
});
This code yields the following on login:
userProvider init
LISTENED: <redacted UID>
uid: <redacted UID>
And then on logout:
LISTENED: null
Where I would expect to see uid: null as well, which would update the stream, but upon any more auth events, only the listener is triggered and no events are caught by the await for loop.
Interestingly, using the flutter inspector, the value emitted by the auth provider never changes, either:
AutoDisposeStreamProvider<FirebaseUser>#95f11: AsyncValue<FirebaseUser>.data(value: FirebaseUser(Instance of 'PlatformUser'))
persists through login/logout events, which could explain this behavior, but I am not sure what to do to fix it.
Any ideas? I have been stuck on this for a while and can't correct the issue.
The problem is, your provider doesn't create a Stream<User> but a Stream<Stream<User>>
As part of 0.6.0-dev, you can use ref.watch to easily combine streams:
class User {
...
static final provider = StreamProvider((ref) {
final auth = ref.watch(AuthService.provider);
return Service.user.stream(auth.uid);
});
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With