void main() async {
...
final AuthenticationProvider authenticationProvider = AuthenticationProvider();
await authenticationProvider.initialize();
runApp(
MultiProvider(
providers: [
Provider<AuthenticationProvider>(create: (_) => authenticationProvider),
StreamProvider<UserModel>(
create: (_) => authenticationProvider.currentUser,
initialData: UserModel(
id: '',
email: '',
displayName: '',
photo: null,
premium: false,
travels: [],
),
)
],
child: MiRoulotte(),
),
);
}
I create a provider that generate a Stream with current user data that change when a user is sign out or sign in, but the data don't change. When I sign out, the stream should be null, and then when I sign in the stream should be the user data.
class AuthenticationProvider {
Stream<UserModel>? _currentUser;
Stream<UserModel>? get currentUser => this._currentUser;
initialize() async {
...
this._currentUser = FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser?.uid)
.snapshots()
.map((user) => UserModel.fromJson(user.data() as Map<String, dynamic>));
...
}
Future signIn({required String email, required String password}) async {
...
this._currentUser = FirebaseFirestore.instance
.collection('users')
.doc(userCredential.user?.uid)
.snapshots()
.map((user) => UserModel.fromJson(user.data() as Map<String, dynamic>));
...
}
Future signOut() async {
...
this._currentUser = null;
...
}
}
You don't actually want your Stream
to be null
but rather have it emit a null
value. The AuthenticationProvider
could have a StreamController
with which you add new values of the current user object onto the streams.
class AuthenticationProvider {
final StreamController _controller = SteamController<UserModel?>();
Stream<UserModel?> get userStream => _controller.stream;
Future<void> initialize() async {
final user = // get usermodel from firebase
_controller.add(user);
}
Future<void> signIn({required String email, required String password}) async {
...
final user = // get usermodel from firebase
_controller.add(user);
}
void signOut() {
_controller.add(null);
}
}
Don't forget to close the StreamController
on dispose:
// in main
Provider<AuthenticationProvider>(
create: (_) => authenticationProvider,
dispose: (provider) => provider.dispose(),
),
// in AuthenticationProvider
void dispose() {
_controller.close();
}