How check if user verify mail and then let logged in? - firebase

I know the question was asking a lot of times but after spending hours trying to understand im still don't know how to doing that.
So right know I got 2 Future methods
the SigIn
Future<String> signIN(String email, String password) async {
try {
(await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email.trim(),
password: password,
))
.user;
} on FirebaseAuthException catch (e) {
switch (e.code) {
case 'invalid-email':
{
return 'Email is not valid';
}
case 'user-disabled':
{
return 'Account is not active';
}
case 'user-not-found':
{
return 'No user found';
}
case 'wrong-password':
{
return 'wrong password';
}
default:
{
return 'Unexpected error!';
}
}
}
return null;
}
And the Sign up
Future<String> signUp(String email, String password) async {
try {
(await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: email.trim(),
password: password,
))
.user
.sendEmailVerification();
} on FirebaseAuthException catch (e) {
switch (e.code) {
case 'invalid-email':
{
return 'Email is not valid';
}
case 'user-disabled':
{
return 'Account is not active';
}
case 'user-not-found':
{
return 'No user found';
}
case 'wrong-password':
{
return 'wrong password';
}
default:
{
return 'Unexpected error!';
}
}
}
return null;
}
And i wish I know how to first check if user verified mail and then let him login.
Right know user press register button and automatically login .
Please help!!
Here the on pressed methods
First the pressed register button
onPressed: () async {
if (_formKey.currentState.validate()) {
String authError = await _auth.signUp(email, password);
if (authError != null) {
setState(() => jawoll = true);
setState(() => error = authError);
}else{
setState(() => loading = true);
setState(() => jawoll = false);
setState(() => error = "Email send to $email");
}
}
}
And the sign in in button
onPressed: () async {
if (_formKey.currentState.validate()) {
String authError = await _auth.signIN(email, password);
if (authError != null) {
setState(() => error = authError);
print("olaaa");
print(error);
}
setState(() => loading = false);
}
}

Remove the stream (authStateChanges) from your widget tree that is responsible for automatically logging in the user.
Then, manually push a new screen for email registration. After it's done let your user go to the home screen.
On opening the app again in the future, you can check if the user is logged in and if the email is verified. If so, move to the home screen and if not to the log in screen.
The problem here is that the stream automatically changes on user login, wether the email is verified or not. So, remove it and proceed !!

Related

Not able to catch error of changing Firebase User email

Since hours I have an Problem with my method. When trying to update use email and the email really exists its works fine. But when I pasting just any sh-- its giving me an error in console but not returning anything . Please help
This is my method
//update in with passwort and email
Future updateemail2(String email, String password, String newemail) async {
try {
UserCredential authResult =
await _auth.currentUser.reauthenticateWithCredential(
EmailAuthProvider.credential(
email: email,
password: password,
),
);
User user = authResult.user;
if (user != null) {
user.verifyBeforeUpdateEmail(newemail);
// user.sendEmailVerification();
}
// user?.emailVerified;
} on FirebaseAuthException catch (e) {
switch (e.code) {
case 'invalid-email':
{
return 'Email ist nicht gültig';
}
case 'email-already-in-use':
{
return 'Email bereits registriert';
}
case 'wrong-password':
{
return 'Passwort ist nicht gültig';
}
case 'internal-error':
{
return "internal error";
}
default:
{
return 'Unexpected Error';
}
return null;
}
}
return null;
}
Im calling it like that
buildupdate(context, userData, user) async {
if (_formKey.currentState.validate()) {
String authError4 = await _auth.updateemail2(
userData.email, userData.password, _currentemail);
if (authError4 != null) {
setState(() {
showerror = true;
error = authError4;
});
} else {
print("halts maul");
}
This is the error which im not able to catch

Firebase Authentication with Flutter not working

I am trying to create a signup page which should give an error message if user with particular email id already exist. But it's not working.
signUp() {
if (formkey.currentState!.validate()) {
Map<String, String> userDataMap = {
"name": usernameC.text,
"email": emailC.text
};
setState(() {
isLoading = true;
});
authMethods.signUp(emailC.text, passwordC.text).then((value) {
databaseMethods.uploadUserData(userDataMap);
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => ChatRoom()));
});
}
}
It calls the signUp() function from auth.dart given below
UserData? _userFromFirebase(User? user) {
return user != null ? UserData(userid: user.uid) : null;
}
Future signUp(String email, String pass) async {
try {
UserCredential result = await _auth.createUserWithEmailAndPassword(
email: email, password: pass);
User? user = result.user;
return _userFromFirebase(user);
} catch (e) {
print(e}
}
Every time I signup with same email it doesn't give any error.
If you sign up with the same email you should get this message:
[firebase_auth/email-already-in-use] The email address is already in use by another account.
I use print(e.hashCode) and then use this hash code to show an error message.
Ok I tried this method and it worked out. Just added null check for the "value" attribute in.
authMethods.signUp(emailC.text, passwordC.text).then((value)
It was returning null without any other message. That's why I was unable to see the error.

Flutter User creation and Signing in

Here is my code
I am trying to run this code with no avail.
import 'package:firebase_auth/firebase_auth.dart';
class AuthClass {
FirebaseAuth auth = FirebaseAuth.instance;
//create account
Future<String> createAccount(
{required String email, required String password}) async {
try {
await auth.createUserWithEmailAndPassword(
email: email, password: password);
return "Account created";
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
return 'The password provided is too weak.';
} else if (e.code == 'email-already-in-use') {
return 'The account already exists for that email.';
}
} catch (e) {
return 'Error Occured';
}
}
//sign in user
Future<String> signIn(
{required String email, required String password}) async {
try {
await auth.signInWithEmailAndPassword(email: email, password: password);
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
return 'No user found for that email.';
} else if (e.code == 'wrong-password') {
return 'Wrong password provided for that user.';
}
}
}
// reset password
Future<String> resetPassword({
required String email,
}) async {
try {
await auth.sendPasswordResetEmail(
email: email,
);
return 'Email Sent';
} catch (e) {
return 'Error Occured';
}
}
//sign out
void signOut() {
auth.signOut();
}
}
I need some help I am getting this error,
The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type.
Try adding either a return or a throw statement at the end.
Future signIn(...) "signIn"
Future createAccount(...) "createAccount"
is where i am getting the error
try on catch blocks work like this.
try executes code. If that fails, it throws an Exception.
Now, that Exception can be of many types and using on and catch together we can catch a specific exception and get that value inside e.
But the on FirebaseAuthException catch (e), only catches Exceptions of type FirebaseAuthException.
So, in a case where your try block throws something else, maybe NumberException, then it won't be caught.
For catching all other types of Exceptions, you need to add another catch block.
Like this,
try {
await auth.signInWithEmailAndPassword(email: email, password: password);
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
return 'No user found for that email.';
} else if (e.code == 'wrong-password') {
return 'Wrong password provided for that user.';
}
} catch (e) {
return 'Unknown Error.'; // Change this to whatever you want.
}
Think of the try like an if block. Then your on FirebaseAuthException catch (e) would be an if else block. But you also need to handle the else block and that is your catch (e).
Hope it makes sense.

Flutter Firestore adding data

I want to add data on firestore and it wont work. can somebody help me.
This is the newest updated version and I can't figure out how...
firebase_auth: ^0.18.0+1 cloud_firestore: ^0.14.0+2
This is the sign up screen so I want to send data after I create the email and password.
I want to add the document with user uid too.
onPressed: () async {
try {
UserCredential userCredential = await FirebaseAuth
.instance
.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
if (userCredential != null) {
firestore
.collection("user")
.doc('user.uid')
.set({
'username': username,
'email': email,
})
.then((value) => print("User Added"))
.catchError((error) =>
print("Failed to add user: $error"));
Navigator.of(context).pushNamed(AppRoutes.authLogin);
}
} catch (e) {
print(e);
_usernameController.text = "";
_passwordController.text = "";
_repasswordController.text = "";
_emailController.text = "";
//TODO: alertdialog with error
}
setState(() {
saveAttempted = true;
});
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
}
},
Can someone help me with the firestore.. Thank you..
First Create a User class.
class UserData {
final String userId;
final String fullNames;
final String email;
final String phone;
UserData(
{this.userId,
this.fullNames,
this.email,
this.phone});
Map<String, dynamic> getDataMap() {
return {
"userId": userId,
"fullNames": fullNames,
"email": email,
"phone": phone,
};
}
}
Then you can use a function like this one to save the credentials and save the data to firestore
createOrUpdateUserData(Map<String, dynamic> userDataMap) async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
DocumentReference ref =
Firestore.instance.collection('user').document(user.uid);
return ref.setData(userDataMap, merge: true);
}
==
bool validateAndSave() {
final form = _formKey.currentState;
if (form.validate()) {
form.save();
return true;
}
return false;
}
void validateAndSubmit() async {
if (validateAndSave()) {
try {
String userId = _formType == FormType.login
? await widget.auth.signIn(_email, _password)//use your signin
: await widget.auth.signUp(_email, _password);//use your signup
if (_formType == FormType.register) {
UserData userData = new UserData(
fullNames: _fullNames,
email: _email,
phone: "",
);
createOrUpdateUserData(userData.getDataMap());
}
} catch (e) {
setState(() {
_isLoading = false;
switch (e.code) {
case "ERROR_INVALID_EMAIL":
_authHint = "Your email address appears to be malformed.";
break;
case "ERROR_EMAIL_ALREADY_IN_USE":
_authHint = "Email address already used in a different account.";
break;
case "ERROR_WRONG_PASSWORD":
_authHint = "Your password is wrong.";
break;
case "ERROR_USER_NOT_FOUND":
_authHint = "User with this email doesn't exist.";
break;
case "EMAIL NOT VERIFIED":
_authHint = "Email not verified: Please go to yor email and verify";
break;
case "ERROR_USER_DISABLED":
_authHint = "User with this email has been disabled.";
break;
case "ERROR_TOO_MANY_REQUESTS":
_authHint =
"Too many Attemps. Account has temporarily disabled.\n Try again later.";
break;
case "ERROR_OPERATION_NOT_ALLOWED":
_authHint = "Signing in with Email and Password is not enabled.";
break;
case "ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL":
_authHint = "The email is in use by another account";
break;
default:
_authHint = "An undefined Error happened.";
}
});
print(e);
errorDialog(context, _authHint);
}
} else {
setState(() {
_authHint = '';
});
}
}
Then use
onpressed:(){
validateAndSubmit();
}
the formtype is an Enum
enum FormType { login, register, reset }
widget.auth.signIn and widget.auth.signUp should be replaced with your signin and signup respectively.
Added a custom error block to differentiate firebase auth errors as well.
Defining an auth page independently will help you reuse your code in future.

How would you check whether or not a username is available in Flutter regarding Firebase?

// Checks for username in our registration authentication.
Future<bool> usernameCheck(String username) async {
final result = await FirebaseFirestore.instance
.collection('users')
.where('username', isEqualTo: username)
.get();
return result.docs.isEmpty;
}
This is my function I created to check usernames in Firebase's Firestore database. This function checks to see if a username is available in the database. In the function below, I convert the username to a text string since signupNameController is the textfield for usernames. It doesn't seem to work as exactly as expected.
onPressed: () async {
if (usernameCheck(signupNameController.text) == true) {
showInSnackBar('Username exists. Please try again');
} else if (usernameCheck(signupNameController.text) == false) {
if (signupPasswordController.text != signupConfirmPasswordController.text) {
showInSnackBar("Passwords don't match.");
} else if (signupEmailController.text == ' ' ||
signupPasswordController.text == ' ' ||
signupNameController.text == ' ' ||
signupConfirmPasswordController.text == '') {
showInSnackBar("Please fill out all the required information.");
} else {
try {
UserCredential userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: signupEmailController.text,
password: signupPasswordController.text,
);
// Our Database collection.
// This will go directly into our Firestore NoSQL database
FirebaseFirestore.instance.collection('users').doc().set({
'username': signupNameController.text.toLowerCase(),
'email': signupEmailController.text,
'password': signupPasswordController.text,
'retypePassword': signupConfirmPasswordController.text
});
Navigator.push(context, MaterialPageRoute(builder: (context) => TabNavigation()));
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
showInSnackBar("The password provided is too weak");
} else if (e.code == 'email-already-in-use') {
showInSnackBar("The account already exists for that email.");
}
} catch (e) {
showInSnackBar(e.toString());
}
}
}
This is what I am trying to accomplish. It doesn't seem to work or input a user. What are some ways to solve this? I am using Flutter and using Firebase for the backend side.

Resources