How to navigate to home screen after successfully login in flutter? - flutter

I'm using the following code for login. But the problem is after successfully login it's not able to navigate to home page. If I navigate inside on pressed button then it automatically navigate to home and it will not check either user exists or not.
try {
final credential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailAddress,
password: password
);
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
}
I have called isUserLoggedIn function after pressing login button.

Change like this,
try {
final credential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailAddress,
password: password
);
//---------------------- add this part --------------
if (user != null) {
Navigator.of(context).pushNamedAndRemoveUntil(
'/home', (Route<dynamic> route) => false);
// route set to use this.
}
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
}
You can also use this method,
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
),
);
But If you use this, the user can back to login screen without signout. So, use pushNamedAndRemoveUntil method to navigate. It will remove all past routes. can't go back.
Read about pushNamedAndRemoveUntil

If you just want to check for the user and navigate based on that, HoRiz has answered.
But I would suggest that you implement a state management solution first like BLoC, Riverpod, etc. It will help you to manage all your data like user info or any other data.
Also if you are not using named routes, then you can use this instead to navigate:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => NewScreen(),
),
);
Also, if want to learn all the things about routing then you can check Flutter's Oficial Website: Link

Navigator.pushReplacement(context,MaterialPageRoute(builder: (context)=>HomePage()));

Related

Problem with the initialRoute of my flutter app

initialRoute: FirebaseAuth.instance.currentUser == null
? "FirstPage"
: FirebaseAuth.instance.currentUser!.emailVerified
? "Home"
: "FirstPage/SignIn/VerificaEmail",
Thanks to this script I know if the user is already logged in, if he has completed the registration or if he has to do everything from the beginning. This way I can send it to the necessary page.
My problem is that before bringing it to the home, if the registration is complete, I want to check if its document exists on the firestore db; otherwise I want to take the user to the appropriate page to enter the data and create the document.
I was able to do this in my login and signin page thanks to the following code:
void verifica(context) async {
var doc = await FirebaseFirestore.instance
.collection("Users")
.doc(FirebaseAuth.instance.currentUser!.uid)
.get();
if (doc.exists) {
Navigator.pushNamedAndRemoveUntil(context, "Home", (route) => false);
} else {
Navigator.pushNamedAndRemoveUntil(context, "ModificaProfilo", (route) => false);
}
}
But I am not able to implement this function in main.

Flutter web firebase auth signInWithPhoneNumber showing error "captcha-check-failed" in release mode

I'm facing a problem with Flutter Web Firebase Phone Auth Verification. In debug it is working well and showing me the reCaptcha. But when I host it through GitHub pages in release mode, it shows an error "captcha-check-failed". Even the capcha isn't showing in release mode.
The signInWithPhoneNumber function:
Future<void> loginWithPhoneRequestOTPWeb(
WidgetRef ref,
GlobalKey<FormState> formKey,
String phoneNumber,
) async {
try {
EasyLoading.show();
await FirebaseAuth.instance
.signInWithPhoneNumber(
phoneNumber,
RecaptchaVerifier(
container: 'recaptcha',
size: RecaptchaVerifierSize.compact,
theme: RecaptchaVerifierTheme.dark,
onError: (e) {
print(e);
EasyLoading.showError(e.message!);
return;
},
onExpired: () {
print('Expired');
EasyLoading.showError('Session Expired');
return;
},
onSuccess: () {
EasyLoading.dismiss();
print('Captcha Success');
},
),
)
.then((ConfirmationResult result) {
// update the verificationphone provider
ref.read(sendOtpProvider(formKey).state).update((_) => true);
ref.read(confirmationResultProvider(formKey).state).update((_) => result);
EasyLoading.showSuccess(t!.otpSentSuccessfully);
});
} on FirebaseAuthException catch (e) {
if (e.code == 'invalid-phone-number') {
print('The provided phone number is not valid.');
EasyLoading.showError('The provided phone number is not valid.');
} else if (e.code == 'too-many-requests') {
print(
'You have exceeded the number of attempts allowed for this operation.');
EasyLoading.showError(
'You have exceeded the number of attempts allowed for this operation.');
} else {
print(e.code.toString());
EasyLoading.showError(e.code.toString());
}
} catch (e) {
print(e.toString());
EasyLoading.showError(e.toString());
}
}
I've tried without the RecaptchaVerifier as it is optional parameter.
Error Screenshot:
If I've missed anything please let me know. Thank You :)
Okay, I've figure out my problem. In the firebase authentication section, there is an "Authorized domains" section. Here I've to add my domains. But firebase only takes .com domains. As a result, I used firebase hosting and it is working fine

Flutter how to stop auto login using firebase SMS

When users first open the app, I want them to authenticate themselves by phone number. When they get the sms code and hit login button, the phone number and other information are sent to the server together.
However, when I press the code verification button, it automatically logs the user in without login button pressing so I cannot send data accordingly.
FirebaseAuth.instance.authStateChanges().listen((user) {
if (user == null) {
print("signed out - MyAppState");
} else {
print("signed in - MyAppState");
Navigator.push(context,
MaterialPageRoute(builder: (context) => BottomBarScreen()));
}
});
try {
_testPhoneValidation(_phoneNumberController.text);
await _auth.verifyPhoneNumber(
phoneNumber: "+82" + _phoneNumberController.text.substring(1),
timeout: const Duration(seconds: 5),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: (verificationId) {},
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('failure: ${e.toString().substring(11)}'),
));
}
this is my current code related to login with Firebase.
I searched how to stop auto login but didn't quite find the right answer.
So I just changed the login logic to : send info when Firebase auth state changes.
There isn't much change in the code and I think it was a dumb mistake that I made not to think about changing the logic.
FirebaseAuth.instance.authStateChanges().listen((user) {
if (user == null) {
print("signed out");
} else {
print("signed in");
signIn();
}
});
Future<void> signIn() async {
await postAppToken(
await _getToken(),
_packageInfo.appName,
_packageInfo.version,
Theme.of(context).platform.toString().substring(15),
await _getPhoneNum())
.then((value) {
print("signIn");
Navigator.push(context,
MaterialPageRoute(builder: (context) => BottomBarScreen()));
}
);
}
So I just added a Future to post related information to the server when user is automatically logged in. This solved my problem.
You should do nothing on " verificationCompleted" callback.
just write like this
verificationCompleted: (PhoneAuthCredential credential) {},
Because verificationCompleted is for automatic handling of the SMS code on Android devices.

Firebase authentication! I'm able to move to home page even if i enter a non registered user

I've successfully added firebase to my flutter2.0 project. I've enables authentication also.I'm able to register a new user also. But the logic to move to home page after authentication is not working. I'm able to login even if I enter a wrong user. I want if I enter proper user then I should navigate to home page, but if the user is not registered it one should not be able to navigate to next page. ie..the basic use of authentication.
But it's not happening here. I'm able to navigate to next place even if I enter wrong user.
Future signInWithEmailAndPassword(String email, String password) async {
try {
UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email:email,
password:password,
);
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
}
}
Future newAccount(String email, String password) async {
try {
UserCredential userCredential = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
}
} catch (e) {
print(e.toString());
}
}
}
//this is how I can this function and try to navigate to next page.
void logMeIn() {
if (formKey.currentState!.validate()) {
authMethods
.signInWithEmailAndPassword(usernameTextEditingContoller.text,
passwordTextEditingContoller.text)
.then((value) {
print('value is: ');
print(value);
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (context) {
return Home();
}));
});
}
}**strong text**
signInWithEmailAndPassword returns a UserCredential object.
In your logic, you are using .then((value) {...etc})
This value is the result of signInWithEmailAndPassword.
Try changing your logic to this:
authMethods
.signInWithEmailAndPassword(usernameTextEditingContoller.text,
passwordTextEditingContoller.text)
.then((value) {
print('value is: ');
print(value);
if(value.user ==null) return "Error in authentication"; // this will prevent your function form going further down the navigation if the usercredential doesn't have a valid user.
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (context) {
return Home();

Flutter Session stores data but can't make decisions based off it

I'm using FlutterSession to store phone number/email (based on user's choice) as a method of logging into the app. The session works fine in case of email but when I store and retrieve phone number, it shows me the snapshot has no data.
This is the method where I'm setting the session value for the phone number:
void phoneSignIn() async {
if (phoneNumber == null || phoneNumber.length < 10) {
print('Please enter a valid phone number!');
}
else {
await fillers.session.set("phoneNum", phoneNumber);
print('Phone number is: '+ phoneNumber);
setState(() {
phoneSignedIn = true;
});
var sessionCheck = await fillers.session.get("phoneNum");
print("Session value: $sessionCheck");
print(phoneSignedIn);
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => OnboardOne()));
}
}
In the above code, I've made sure using print statements that the session is storing phone number value and also that the phoneSignedIn bool is set to true.
This is the method where I'm setting session value for email:
void signIn() async {
response = await Dio().post(url,
data: {
"email": emailVal,
"password": passwordVal
}
);
if (response.statusCode == 200) {
await fillers.session.set('email', emailVal);
await fillers.session.set('password', passwordVal);
print('Sign In successful!');
print('Email: $emailVal');
print('Password: $passwordVal');
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => OnboardOne()));
}
else
{
print('Exited with statuscode ${response.statusCode}');
print('Email: $emailVal');
print('Password: $passwordVal');
}
}
This is my firstpage where I decide on which page to go based on whether the user has logged in or not:
class _FirstPageState extends State<FirstPage> {
#override
Widget build(BuildContext context) {
return Material(
child: FutureBuilder(
future: phoneSignedIn ? session.get("phoneNum") : session.get('email'),
builder: (context, snapshot) {
return snapshot.hasData ? Dashboard() : SignUpIn();
}
),
);
}
}
As you can see, I've done nothing different in the email sign in (except using a backend api to auth the email). Ultimately, I'm using the same technique to store both the email and phone number. But when I've signed in using phone number and then reopen the app, the app goes to the SignUpIn() page, when it should actually go to the Dashboard() page.
Also, on the dashboard, there's a button "Sign Out", on pressing which, the session values are cleared.
What am I doing wrong?