Firebase confirmation email not being sent - firebase

I've set up Firebase email/password authentication successfully, but for security reasons I want the user to confirm her/his email.
It says on Firebases website:
When a user signs up using an email address and password, a confirmation email is sent to verify their email address.
But when I sign up, I doesn't receive a confirmation email.
I've looked and can only find a code for sending the password reset email, but not a code for sending the email confirmation.
I've looked here:
https://firebase.google.com/docs/auth/ios/manage-users#send_a_password_reset_email
anyone got a clue about how I can do it?

I noticed that the new Firebase email authentication docs is not properly documented.
firebase.auth().onAuthStateChanged(function(user) {
user.sendEmailVerification();
});
Do note that:
You can only send email verification to users object whom you created using Email&Password method createUserWithEmailAndPassword
Only after you signed users into authenticated state, Firebase will return a promise of the auth object.
The old onAuth method has been changed to onAuthStateChanged.
To check if email is verified:
firebase.auth().onAuthStateChanged(function(user) {
if (user.emailVerified) {
console.log('Email is verified');
}
else {
console.log('Email is not verified');
}
});

After creating a user a User object is returned, where you can check if the user's email has been verified or not.
When a user has not been verified you can trigger the sendEmailVerification method on the user object itself.
firebase.auth()
.createUserWithEmailAndPassword(email, password)
.then(function(user){
if(user && user.emailVerified === false){
user.sendEmailVerification().then(function(){
console.log("email verification sent to user");
});
}
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorCode, errorMessage);
});
You can also check by listening to the AuthState, the problem with the following method is, that with each new session (by refreshing the page),
a new email is sent.
firebase.auth().onAuthStateChanged(function(user) {
user.sendEmailVerification();
});

The confirmation email could be in your spam folder.
Check your spam folder.

You can send verification email and check if was verified as follow into the AuthListener:
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
//---- HERE YOU CHECK IF EMAIL IS VERIFIED
if (user.isEmailVerified()) {
Toast.makeText(LoginActivity.this,"You are in =)",Toast.LENGTH_LONG).show();
}
else {
//---- HERE YOU SEND THE EMAIL
user.sendEmailVerification();
Toast.makeText(LoginActivity.this,"Check your email first...",Toast.LENGTH_LONG).show();
}
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
}
// [START_EXCLUDE]
updateUI(user);
// [END_EXCLUDE]
}
};

if you're using compile "com.google.firebase:firebase-auth:9.2.0" and
compile 'com.google.firebase:firebase-core:9.2.0' the method sendEmailVerification() will not be resolved until you update to 9.8.0 or higher. It wasted most of time before I figured it out.

I have been looking at this too. It seems like firebase have changed the way you send the verification. for me
user.sendEmailVerification()
did not work.
If you get an error such as user.sendEmailVerification() doesn't exist.
use the following.
firebase.auth().currentUser.sendEmailVerification()

It's not the answer to the question but might help someone.
Don't forget to add your site domain to the Authorised domains list under Sign-in-method

You could send a verification email to any user whose email is linked to the Firebase Auth account. For example, in Flutter you could do. something like :
Future<void> signInWithCredentialAndLinkDetails(AuthCredential authCredential,
String email, String password) async {
// Here authCredential is from Phone Auth
_auth.signInWithCredential(authCredential).then((authResult) async {
if (authResult.user != null) {
var emailAuthCredential = EmailAuthProvider.getCredential(
email: email,
password: password,
);
authResult.user
.linkWithCredential(emailAuthCredential)
.then((authResult,onError:(){/* Error Logic */}) async {
if (authResult.user != null) {
await authResult.user.sendEmailVerification().then((_) {
debugPrint('verification email send');
}, onError: () {
debugPrint('email verification failed.');
});
}
});
}
});
}

Related

how to send verification email to users using Firebase Auth

I want to send verification email to users who just signed up. I have been looking for a solution for this and thought I found one, but it didn't work.
I checked out the Firebase Auth document and tried code on the page, but it also couldn't be the solution.
My code is below
The "try" actually runs when pressing the sign-up button and I can see it.
In the Firebase Auth console page, I can see the user just created but didn't get a verification email in the inbox.
const handleSignup = async (email, pswd) => {
try {
await createUserWithEmailAndPassword(auth, email, pswd);
setSignupEmail("");
setSignupPassword("");
setSignupPasswordAgain("");
signOut(auth);
sendEmailVerification(auth.currentUser);
alert("Check your email for a verification link.");
} catch (err) {
console.log(err);
}
};
You call sendEmailVerification() after having called signOut() so auth.currentUser is null when you pass it to sendEmailVerification(). You should see an error logged in the catch block.
Moreover, both sendEmailVerification() and signOut() methods are asynchronous and return Promises.
The following should do the trick (untested):
const handleSignup = async (email, pswd) => {
try {
await createUserWithEmailAndPassword(auth, email, pswd);
setSignupEmail("");
setSignupPassword("");
setSignupPasswordAgain("");
await sendEmailVerification(auth.currentUser);
await signOut(auth);
alert("Check your email for a verification link.");
} catch (err) {
console.log(err);
}
};

Flutter FirebaseAuth: SignUp unable to handle error when the email address is used by another user

My code here, and the error pointed at -> await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: email.trim(), password: password.trim()); - in code below
Future SignUp() async {
try {
UserCredential result = await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: email.trim(), password: password.trim());
User user = result.user;
return user;
} on FirebaseAuthException catch (e) {
print(e);
if (e.code == 'email-already-in-use') {
setState(
() // setState rebuilds the entire build by modifying the code inside it
{
error = e.toString();
EmailExists =
true; //sets the emailExists variable to 'true' and rebuild
});
}
}
}
Error:
PlatformException (PlatformException(firebase_auth, com.google.firebase.auth.FirebaseAuthUserCollisionException: The email address is already in use by another account., {message: The email address is already in use by another account., additionalData: {}, code: email-already-in-use}, null))
By default Firebase Authentication only allows a single user to register with a specific email address in a project. When a second user tries to register with the same email address, you get the error that you have and you'll need to handle that scenario in your code. Typically you'll tell the user that the email address has already been registered and either ask them for their password, or tell them to use another email address.
If you want to allow multiple users to register with the same email address, you can enable that by changing the Multiple accounts per email address setting in the Sign-in methods pabel of the Firebase console.

Change password of firebase user in flutter

I want to change the password of a firebase account. To do that the user should enter the old password before. If it is correct then he is allowed to change pass. I used this code which is only for changing the pass and not comparing the old one.
void _changePassword(String password) async{
//Create an instance of the current user.
FirebaseUser user = await FirebaseAuth.instance.currentUser();
//Pass in the password to updatePassword.
user.updatePassword(password).then((_){
print("Successfully changed password");
}).catchError((error){
print("Password can't be changed" + error.toString());
//This might happen, when the wrong password is in, the user isn't found, or if the user hasn't logged in recently.
});
}
The idea is to verify old password by resigning in user using firebaseAuth, you can get user email by passing user.email to string, and let user input old password. If sign in proccess failed, password change shouldn't happen.
void _changePassword(String password) async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
String email = user.email;
//Create field for user to input old password
//pass the password here
String password = "password";
String newPassword = "password";
try {
UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
user.updatePassword(newPassword).then((_){
print("Successfully changed password");
}).catchError((error){
print("Password can't be changed" + error.toString());
//This might happen, when the wrong password is in, the user isn't found, or if the user hasn't logged in recently.
});
} 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.');
}
}
}
it will not allow you to verify its previous or old password . it will directly send email for forgot and there you need to add your new password . and and you have to back again to application and your password will be updated as you wil try to login .
If the user hasn't signed in recently, Firebase will automatically require them to reauthenticate before they can change their password (or perform other sensitive operations). So you typically should only require the user to reauthenticate when Firebase tells you to.
When that happens, follow the steps in the documentation on reauthenticating a user.

Firebase + Flutter: can't lock access to unverified email accounts

I'd like to block out people who didn't verify their email so i figured out this code for sign up:
// sign up
Future signUp(String email, String password) async {
try {
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
} catch (e) {
print('An error has occured by creating a new user');
print(
e.toString(),
);
}
try {
final FirebaseUser _user = await _auth.currentUser();
await _user.sendEmailVerification();
} catch (error) {
print("An error occured while trying to send email verification");
print(error.toString());
}
try {
await _auth.signOut();
} catch (err) {
print(err);
}
}
and this for sign in:
//Sign In with Email and Pass
Future signInWithEmailAndPassword(String email, String password) async {
FirebaseUser _user = await FirebaseAuth.instance.currentUser();
if (_user != null && _user.isEmailVerified == true) {
try {
await _auth.signInWithEmailAndPassword(
email: email, password: password);
return _user;
} catch (e) {
return null;
}
} else {
return null;
}
}
_auth is just an instance of FirebaseAuth.
The problem is that i can login even if i didnt verify the email.
Firebase Auth doesn't stop accounts from signing in if the user hasn't verified their email address yet. You can check that property _user.isEmailVerified to find out the state of that validation after the user signs in, and you can determine from there what the user should see.
isEmailVerified can be a little bit of trouble to get working correctly.
Make sure you are calling
await FirebaseAuth.instance.currentUser()..reload();
before your are calling isEmailVerified also in my own experience and I don't know if this is just something I was doing wrong but this did not work from my Auth class this did not start working until I put the code directly in initState() of my widget that checks whether the user is verified. Like I said that part might have been something I did wrong. Like stated this will not listen for change you must check yourself either periodically or at a point that you know email is verified.
Future(() async {
_timer = Timer.periodic(Duration(seconds: 10), (timer) async {
await FirebaseAuth.instance.currentUser()
..reload();
var user = await FirebaseAuth.instance.currentUser();
if (user.isEmailVerified) {
timer.cancel();
Navigator.of(context).popAndPushNamed(HearingsScreen.routeName);
}
});
});
So it checks every 10 seconds to see if the user has verified their email not the most elegant solution. The page I have this on just displays a message 'Please verify your email' so its not like this is interrupting other code. If your app is performing other tasks this might not be an option for you. If you want to play around with isEmailVerified go ahead but i spent a week of headaches until i settled on this.

How to verify an email in firebase auth in flutter?

I've created a login screen using firebase & flutter and Everything is going okay but I want the user to sign in with a real email (verified) not any email.
if the user clicks signs in button with an email like that : shsuhsafk#uisl.com, it will accept this email.
how to verify that the email isn't fake and actually belong to a real address.
In order to really verify the users e-mail address you need to send a verification mail which requires action from the user.
Only checking if the address exists is insufficient as the e-mail address could belong to anyone.
You can set up a mail template in your Firebase Console and use the following code to send the verification mail.
FirebaseUser user = await _firebaseAuth.createUserWithEmailAndPassword(email: email, password: password);
try {
await user.sendEmailVerification();
return user.uid;
} catch (e) {
print("An error occured while trying to send email verification");
print(e.message);
}
}
String email = "user#example.com";
try {
String link = FirebaseAuth.getInstance().generateSignInWithEmailLink(
email, actionCodeSettings);
// Construct email verification template, embed the link and send
// using custom SMTP server.
sendCustomPasswordResetEmail(email, displayName, link);
} catch (FirebaseAuthException e) {
System.out.println("Error generating email link: " + e.getMessage());
}
Please refer Below link for more info: https://firebase.google.com/docs/auth/admin/email-action-links

Resources