I am looking for the right way of implementing streams using bloc. I have a appUser
of type AppUser
which changes based on the stream
. I want to listen to this appUser
throughout the application using bloc
.
My present implementation .
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(lazy: false, create: (context) => UserCubit())
],
child: MaterialApp(
theme: customTheme(context),
home: const MyWidget(),
));
}
UserCubit.dart
class UserCubit extends Cubit<UserState> {
final _firestore = FirebaseFirestore.instance;
final User? _currentUser = FirebaseAuth.instance.currentUser;
AppUser? appUser;
UserCubit() : super(UserInitialState()) {
emit(UserMainLoadingState());
_firestore
.collection("users")
.doc(_currentUser?.uid) // or whatever your collection name is
.snapshots()
.listen((event) {
event.exists
? {
print(" The user is ${event.data()}"),
appUser = AppUser.fromjson(event.data()!, event.id), // here it changes
emit(UserExists(user: appUser!))
}
: {print("Oops no user"), emit(UserNotExists())};
});
}
MyWidget.dart
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(body: Center(
child: BlocBuilder(builder: (context, state) {
return Text(BlocProvider.of<UserCubit>(context).appUser.toString()); // I want to get the changes of appUser
})));
}
}
CodePudding user response:
You should move your AppUser
to the UserState
like this:
abstract class UserState extends Equatable {
final AppUser? appUser;
const UserState({this.appUser});
@override
List<Object?> get props => [appUser];
}
class UserExists extends UserState {
const UserExists({required AppUser user}) : super(appUser: user);
}
And then you can read it from state of your BlocBuilder
like so:
BlocBuilder<UserCubit, UserState>(
builder: (context, state) {
return Text(state.appUser.toString());
},
);