I want to implement a reset password form. For that I need to check whether the text input email that user input in out text field is present in our firebase authentication database or not, so that if it is I can send Reset password mail or else show him a pop-dialog to rectify the email.
I've already applied the email checking part where I check wether the text is Email or not.
Firebase Auth can actually manage that for you. Simply call the sendPasswordResetEmail() method like this:
_auth.sendPasswordResetEmail(email: email)
.then((void v) => {
// password reset email sent successfully
})
.catchError((Error error) => {
// There was an error verifying the email
// Check the output of error.toString()
// This is where you may want to show a pop-up dialog
});
If the email is badly formatted or if the email is not present on the Auth Database, the code will always execute the catchError method.
Related
Whenever I use the email/password authentication provider in Firebase, the provider sends a bearer token upon successful sign-up even though the emailVerified is false. Is there a way, out of the box, to configure the email/password auth provider to not send a bearer token (and return a 403 error) until the user has verified their email address?
Note that I'm aware of how to create a user, sign in a user, send a verification email, etc... using firebase v9.x via the methods createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut, sendEmailVerification from firebase/auth. I'm just asking if there is a way to set the behavior of the provider without having to write my own handler function for this. I'd like this to behave like Cognito does whenever the email verification is required.
There is no way to require the user's email address to be verified before they can sign in to Firebase Authentication.
The closest you can get is by using email-link sign-in, which combines signing in and verifying the user's email address in one action.
But this is how you'll typically want to implement this in your application code:
User enters their credentials
You sign them in to Firebase with those credentials
You check whether their email address is verified
If not, you stop them from further using the app - and (optionally) send them a verification email.
Same with data access: if you have a custom backend code, you can check whether the email address is verified in the ID token there too, as well as in Firebase's server-side security rules.
As per the documentation, you can use blocking functions to require email verification for registration (only that it doesn't work):
exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
const locale = context.locale;
if (user.email && !user.emailVerified) {
// Send custom email verification on sign-up.
return admin.auth().generateEmailVerificationLink(user.email).then((link) => {
return sendCustomVerificationEmail(user.email, link, locale);
});
}
});
exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
if (user.email && !user.emailVerified) {
throw new functions.auth.HttpsError(
'invalid-argument', `"${user.email}" needs to be verified before access is granted.`);
}
});
generateEmailVerificationLink always returns the following error:
"err": {
"message": "There is no user record corresponding to the provided identifier.",
"code": "auth/user-not-found"
},
but the user is created anyway given that beforeCreate don't return an exception.
If you want to check by yourself just log the error:
return admin.auth().generateEmailVerificationLink(user.email)
.then((link) => {
functions.logger.info("link", {user: user, context: context, link: link})
})
.catch((err) => {
functions.logger.info("error", {user: user, context: context, err: err});
});
The createUserWithEmailAndPassword() will sign in user right after the account is created. Also there isn't any way to prevent users from logging in even if their email is not verified but you can actually check if email is verified in security rules or using Admin SDK to prevent users with unverified email from accessing your resources. You can use this rule in Firestore:
allow read, write: if request.auth.token.email_verified == true;
One workaround would be creating users using a Cloud function and Admin SDK which won't sign in users but do note that users can sign in.
If you want to prevent login unless the email is verified strictly, then you can disable account right after it is created. Now you may not be able to use sendEmailVerification() which requires user to be signed in at first place, you can always create your own solution for verifying email. The process might look something like:
Create a user and disable the account in a Cloud function
Generate some token or identifier for verifying email and send an email to user from same cloud function
Once the user visits that link and verifies the email you can enable it
Additionally, users can still create accounts by using REST API but you can disable sign ups so users can be created via Cloud function only which disables the user immediately.
I have implemented email verification in my app but i've noticed to email providers have bots that open the link before the user gets to see (thus verifying the email).
is there a way to prevent such behavior? or email verification by code or have action on the screen the user would need to click to verify?
Rather than providing a direct link to Firebase (the default), you can customize your email verification template to direct the user to another location, such as your application, where they must press a button to complete the verification process. Then you can use the Auth.applyActionCode() method with the oobCode that was supplied in the query parameters.
You'll have to process the verifications yourself if you wish to customize it. You can try it by generating email verification link using Admin SDK in a Cloud Function/Server
// Admin SDK API to generate the email verification link.
const useremail = 'user#example.com';
admin
.auth()
.generateEmailVerificationLink(useremail, actionCodeSettings)
.then((link) => {
// Construct email verification template, embed the link and send
// using custom SMTP server.
return sendCustomVerificationEmail(useremail, displayName, link);
})
.catch((error) => {
// Some error occurred.
});
Now that you've sent the email, you'll have to self-host a page to that opens after opening that link.
You can find detailed explanation in the documentation
That being said, you can implement reCaptcha or any verification service you want to use to make sure the user is not a bot and verify it in your custom handler.
Firebase provides email templates for most user email such as password reset but doesn't provide one for the email sent via the sendSignInLinkToEmail method.
It is possible to either customise the content of this email or even better simply get generated link and then use your own email delivery system to sent the email?
You can't modify the built-in templates, however you can make use of the Admin SDKs to generate the action links.
This process is documented here.
const destEmail = 'user#example.com';
admin.auth().generateSignInWithEmailLink(destEmail, actionCodeSettings)
.then((link) => {
// Construct sign-in with email link template, embed the link and
// send using custom SMTP server.
return sendSignInEmail(destEmail, displayName, link);
})
.catch((error) => {
// Some error occurred.
});
What i want to know is without login get Auth User UID from firebase
that already registered user
I already read firebase document but all the explain focus on when user logged only at that time can get UID...
but i just want to get UID and user email address without login situation
Is there any way?
Nope, there is no way using firebase authentication to retrieve the uid or email is the user is currently not logged in.
The only other way to actually retrieve them, is to use firebase database. So, when the user registers in your application, you also send the data of the user to the database and then you will be able to retrieve the data later on even if he is not logged in.
For example (on register) you can send this data to the database:
users
userId
email : email_here
name : name_here
Your question is not clear.
You can create the user via the Admin SDK if you know the user's credentials. You can also lookup an existing user's information by email or uid with the Admin SDK.
Learn more about this from the official docs.
You can apply a trick to do this. Though this is not an optimal solution.
One thing you have to remember that, "There is no way to get a UID without login".
Create a dummy user from your backend with a dummy email and password.
Send the email and password from the backend to your client-side app. You can always hash the password if you want to give an extra security layer.
Now call signInWithEmailAndPassword function from firebase SDK and provide email and password which came from the backend.
The user is already registered in the backend, so now you can get the UID from your client app.
mAuth.signInAnonymously()
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInAnonymously:success");
FirebaseUser user = mAuth.getCurrentUser();
Log.d("userstatus","user id is "+user.getUid());
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInAnonymously:failure", task.getException());
}
// ...
}
});
I am using AngularFireStore and AngularFireAuth. I am able to create users via email and password. I am also able to verify a users email successfully. However, when I update a users email address there is no email sent to the user to alert them to the change. The email address update is successful though.
According to the docs I had the impression this process was automatic.
Text from image:
For security, when a user changes their email address, an email is sent to their original address so they can review the change.
The relevant code I have for updating an email address is below:
firebaseUser: Observable<firebase.User>;
updateUserEmail(newEmail: string) {
return this.firebaseUser.pipe(switchMap(user => from(user.updateEmail(newEmail))));
}
test() {
this.authService.updateUserEmail('example#example.com').subscribe(result => console.log(result));
}
Am I doing something wrong that is causing the Email Address Change transactional email not to be sent?