This is the state class Code
class SignInState {
String email;
String password;
bool passwordVisible;
SignInState(
{this.email = "", this.password = "", this.passwordVisible = false});
List<Object> get props => [this.email, this.password, this.passwordVisible];
SignInState copyWith(
{String? email, String? password, bool? passwordVisible}) {
return SignInState(
email: email ?? this.email,
password: password ?? this.password,
passwordVisible: passwordVisible ?? this.passwordVisible);
}
}
// class SignInInitial extends SignInState {
// SignInInitial({
// String email = "",
// String password = "",
// bool passwordVisible = false,
// }) : super(
// email: email, password: password, passwordVisible: passwordVisible);
// }
class SignInLoading extends SignInState {}
class SignInSuccess extends SignInState {}
class SignInError extends SignInState {
final String error;
SignInError({required this.error});
}
This is the event class code
@immutable
sealed class SignInEvent {}
class SignInEmailEvent extends SignInEvent {
final String email;
SignInEmailEvent({required this.email});
}
class SignInPasswordEvent extends SignInEvent {
final String password;
SignInPasswordEvent({required this.password});
}
class SignInPasswordVisibleEvent extends SignInEvent {
final bool passwordVisible;
SignInPasswordVisibleEvent({required this.passwordVisible});
}
class SignInLoginButtonEvent extends SignInEvent {}
class SignInRegisterButtonEvent extends SignInEvent {
final String email;
final String password;
SignInRegisterButtonEvent({required this.email, required this.password});
}
**This is the BloC Code**
class SignInBloc extends Bloc<SignInEvent, SignInState> {
SignInBloc() : super(SignInState()) {
on<SignInEmailEvent>((event, emit) {
// print("Email is ${event.email}");
emit(state.copyWith(
email: event.email,
));
});
on<SignInPasswordEvent>((event, emit) {
// print("Email is ${event.password}");
emit(state.copyWith(password: event.password));
});
on<SignInPasswordVisibleEvent>(
(event, emit) =>
emit(state.copyWith(passwordVisible: event.passwordVisible)),
);
on<SignInLoginButtonEvent>(
(event, emit) async {
String email = state.email;
String password = state.password;
print("Email is $email" + "Password is $password");
if (email.isEmpty) {
// print("Please enter email and password");
emit(SignInError(error: "Please Enter Email"));
} else if (password.isEmpty) {
// print("Please enter email and password");
emit(SignInError(error: "Please Enter password"));
}
try {
final credential = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
// print("I am Here");
if (credential.user == null) {
// print("User Not Found");
emit(SignInError(error: "User Not Found"));
}
if (credential.user!.emailVerified == false) {
// print("Email Not Verified");
emit(SignInError(error: "Email Not Verified"));
}
var user = credential.user;
if (user != null) {
emit(SignInSuccess());
//emit(SignInSuccess());
}
} on FirebaseAuthException catch (e) {
if (e.code == "user-not-found") {
//print("User Not Found");
emit(SignInError(error: "User Not Found"));
} else if (e.code == 'wrong-password') {
//print("Wrong Password");
emit(SignInError(error: "Wrong Password"));
} else if (e.code == 'invalid-email') {
//print("Invalid Email");
emit(SignInError(error: "Invalid Email"));
}
}
},
);
}
}
I couldn't find where I am doing it wrong. Typing email and pressing the signup button print- Email is miraj Password is Typing pass and pressing the signup button print-Email is Password is 123 Why is the email/password setting null? Also, setting the email and passing it together print-Email is miraj Password is 123 tapping again **print-Email is Password is ** Both are set to null. How can I resolve this problem?
As soon as you call emit(SignInSuccess());
you are changing your current state to a state without any data in email and password.
Don't use the state
property of the BaseBloc
class, instead supply the variables through the event.
The form triggers the SignInLoginEvent
which will be handled by the bloc. A bloc basically translates events to states. The UI uses a BlocBuilder
to show different things depending on the state which was emited from the bloc. Please note that the BlocBuilder
needs to be a (not necessarily direct) child of a BlocProvider
of the same type.
@immutable
sealed class SignInEvent {}
class SignInLoginEvent extends SignInEvent {
final String? email;
final String? password;
SignInLoginEvent({this.email, this.password});
}
class SignInState {}
class InitialState extends SignInState {}
class SignInLoading extends SignInState {}
class SignInSuccess extends SignInState {}
class SignInError extends SignInState {
final String error;
SignInError({required this.error});
}
class SignInBloc extends Bloc<SignInEvent, SignInState> {
SignInBloc() : super(InitialState()) {
on<SignInLoginEvent>(
(event, emit) async {
String? email = event.email;
String? password = event.password;
if (kDebugMode) {
print("Email is $email and password is $password");
}
if (email != null && email.isEmpty) {
emit(SignInError(error: "Please Enter Email"));
} else if (password != null && password.isEmpty) {
emit(SignInError(error: "Please Enter password"));
}
emit(SignInLoading());
try {
final credential = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
if (credential.user == null) {
emit(SignInError(error: "User Not Found"));
}
if (credential.user!.emailVerified == false) {
emit(SignInError(error: "Email Not Verified"));
}
var user = credential.user;
if (user != null) {
emit(SignInSuccess());
}
} on FirebaseAuthException catch (e) {
if (e.code == "user-not-found") {
emit(SignInError(error: "User Not Found"));
} else if (e.code == 'wrong-password') {
emit(SignInError(error: "Wrong Password"));
} else if (e.code == 'invalid-email') {
emit(SignInError(error: "Invalid Email"));
}
}
},
);
}
}
class Login extends StatefulWidget {
const Login({Key? key}) : super(key: key);
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => SignInBloc(),
child: const LoginPage(),
);
}
}
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
@override
Widget build(BuildContext context) {
String? email, password;
return BlocBuilder<SignInBloc, SignInState>(
builder: (context, state) => Form(
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(label: Text('Username')),
onChanged: (value) => email = value,
),
TextFormField(
decoration: const InputDecoration(label: Text('Password')),
obscureText: true,
onChanged: (value) => password = value,
),
ElevatedButton(onPressed: () => {
context.read<SignInBloc>().add(SignInLoginEvent(email: email, password: password));
}, child: const Text('Login')),
switch (state) {
SignInLoading() => const Text('Trying to sign in...'),
SignInSuccess() => const Text('Successful signed in'),
SignInError() => Text(state.error),
_ => const Text(''),
}
],
),
),
);
}
}