For a certain area I want to have my user registred and verified with BOTH:
his EMAIL adress and his PHONE NUMBER. After email and phone was verified, I link the EMAIL to the PHONE with these lines of code:
mAuth.getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()) {
FirebaseUser user = task.getResult().getUser();
if(config.debugcode) {Log.e("LINKING successful",user.toString());
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplication());
prefs.edit().putBoolean("locked", false).apply();
Now Firebase gives me the possibility to check if the EMAIL was verified with the following code:
if (user.isEmailVerified()) { }
But how can I check, if my User with the LINKED Credential (EMAIL to PHONE) has BOTH of it verified?
Use FirebaseAuth.getInstance().getCurrentUser().sendEmailVerification() and FirebaseAuth.getInstance().getCurrentUser().isEmailVerified()
This can let you know whether the email has been verified or not. Read more about email and phone authentication in Firebase, here.
Also visit, this link to know more about how to use this feature.
UPDATE
The above code helps you identify if the user has verified the email or not, but currently there's no method to find if the user has got his phone number verified.
For this you have to do it manually, what you can do is that when you you verify OTP and let user login with phone number, you can update a node in Json, with boolean value 'true` that tells you, that user has got his number verified.
Now to see which user has his phone number verified, you can run a code like this:
DatabaseRef userRef = FirebaseDatabase.getInstance.getRef("users");
userRef.orderByChild("phoneVerified").equalTo(true).addListenerForSingleValueEvent(new ValueEventListener() {
if (dataSnapshot.getValue() != null){
//it means user already registered
//Add code to show your prompt
showPrompt();
}else{
//It is new users
//write an entry to your user table
//writeUserEntryToDB();
}
}
Related
i would like to add an email address for a user who chose phone authentication and add a phone number for a user who is authenticated using email or google sign-in.
According official doc, you can set a user's email address with the updateEmail method like:
In Java:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.updateEmail("user#example.com")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User email address updated.");
}
}
});
In Kotlin:
val user = FirebaseAuth.getInstance().currentUser
user?.updateEmail("user#example.com")
?.addOnCompleteListener { task ->
if (task.isSuccessful) {
Log.d(TAG, "User email address updated.")
}
}
You can merge authentications using linkWithCredential()
auth.getCurrentUser().linkWithCredential(credential)
check this link https://firebase.google.com/docs/auth/android/account-linking
Updating or adding an email is important and sensitive information, the other answers although highlight the important steps, they forget to mention that the user has to be recently authenticated for their solutions to work. If the user is not recently authenticated Firebase throws an exception - FirebaseAuthRecentLoginRequiredException (see documentation).
Let's walk through the official docs examples.
Update or adding email address (docs)
val user = FirebaseAuth.getInstance().currentUser
user?.updateEmail("user#example.com")?.addOnCompleteListener { task ->
if (task.isSuccessful) {
Log.d(TAG, "User email address updated.")
}
}
What to do in case the user is not authenticated recently?
Re-authenticated the user (docs)
Again taken straight out of the docs:
// Get auth credentials from the user for re-authentication. The example below shows
// email and password credentials but there are multiple possible providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
val credential = EmailAuthProvider
.getCredential("user#example.com", "password1234")
// Prompt the user to re-provide their sign-in credentials
user?.reauthenticate(credential)
?.addOnCompleteListener { Log.d(TAG, "User re-authenticated.") }
In your case, the credential provider will be PhoneAuthProvider.
You should add a boolean variable to the database that user has inserted email or not.
initially, the value of this variable will be false. if user signed in via phone number make this variable false else change it to true.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I want to make an app which takes in both the email id and contact number of an user(besides some other fields) using Firebase. After that I want to verify both the email id and the contact number of the user by sending an OTP to the user's contact number and a verification email to the user's email id. Can it be done in Firebase? If so then please guide me how. I am using Android Studio.
I believe this is possible, although it will be kind of tricky. You will have to implement both email and phone number and on the callbacks add a check to see if both were completed before signing the user in. I think given that email seems to have to sign the user in, you will have to implement phone verification to occur first before email and add a check that the phone was verified before checking email and signing in. Shown in the documentation:
Setup the phone verification as stated in the documentation and for the callbacks
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
// This callback will be invoked in two situations:
// 1 - Instant verification. In some cases the phone number can be instantly
// verified without needing to send or enter a verification code.
// 2 - Auto-retrieval. On some devices Google Play services can automatically
// detect the incoming verification SMS and perform verification without
// user action.
Log.d(TAG, "onVerificationCompleted:" + credential);
//signInWithPhoneAuthCredential(credential); //send email for email verification here instead/ sign in with email method
}
Maybe send the email verification once the phone number is confirmed like this
//Save the user email address beforehand for this
FirebaseAuth auth = FirebaseAuth.getInstance();
auth.sendSignInLinkToEmail(email, actionCodeSettings)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Email sent.");
}
}
});
Implement this https://firebase.google.com/docs/auth/android/email-link-auth#completing_sign-in_in_an_android_app to setup dynamic links to complete sign in within the app
and have something like this for the signing in with email method.
FirebaseAuth auth = FirebaseAuth.getInstance();
Intent intent = getIntent();
String emailLink = intent.getData().toString();
// Confirm the link is a sign-in with email link.
if (auth.isSignInWithEmailLink(emailLink)) {
// Retrieve this from wherever you stored it
String email = "someemail#domain.com";
// The client SDK will parse the code from the link for you.
auth.signInWithEmailLink(email, emailLink)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Successfully signed in with email link!");
AuthResult result = task.getResult();
// You can access the new user via result.getUser()
// Additional user info profile *not* available via:
// result.getAdditionalUserInfo().getProfile() == null
// You can check if the user is new or existing:
// result.getAdditionalUserInfo().isNewUser()
} else {
Log.e(TAG, "Error signing in with email link", task.getException());
}
}
});
}
I would think there is a better way to approach this. Maybe some kind of cloud function in the console, but this is the only approach I can find for now.
So I am trying to implement a change password feature. I am able to to do it using updatePassword (newPassword) method. I would like to do some verification before this.So for example when the user wants to change his password, he presses a button and then:
User enters current password
User enters new password
User enters new password again.
How do I verify that the current password the user inputted is correct? There does not seem to be a method that gets me the current password of the user to compare it with.
What you are looking for is "Re-authenticate a user" which is discussed in Firebase's authentication documention. The idea is that you must have the user re-enter their old information into the user.reauthenticate method and firebase will verify the information and you continue operations in onComplete if successful, or firebase sends you an exception. You would use updatePassword in onComplete like below. Your UI would look like its one transaction but really its reAuthenticate -> updatePassword. You additionally may be able to assume the user username/email based on how you store user information.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String newPassword = "SOME-SECURE-PASSWORD";
// Get auth credentials from the user for re-authentication. The
//example below shows
// email and password credentials but there are multiple possible
//providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
AuthCredential credential = EmailAuthProvider
.getCredential("user#example.com", "password1234");
// The email and password should be extracted from an EditText
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d(TAG, "User re-authenticated.");
user.updatePassword(newPassword)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User password updated.");
}
}
});
}
});
I want to implement change password functionality for my application.
I included com.google.firebase:firebase-auth:9.0.2 in my build.gradle file and so far everything has been working fine until I tried to implement change password functionality.
I found that the FirebaseUser object has a updatePassword method that takes a new password as the parameter. I could use this method and implement validation myself. However, I need the user's current password for comparing with the inputted one and I can't find a way to get that password.
I also found another method on the Firebase object that takes the old password, new password, and a handler. The problem is that I need to also include com.firebase:firebase-client-android:2.5.2+ to access this class and when I am trying this method I'm getting to following error:
Projects created at console.firebase.google.com must use the new Firebase Authentication SDKs available from firebase.google.com/docs/auth/
Feel like I'm missing something here. What's the recommended approach for implementing this? And when to use what dependency?
I found a handy example of this in the Firebase docs:
Some security-sensitive actions—such as deleting an account, setting a
primary email address, and changing a password—require that the user
has recently signed in. If you perform one of these actions, and the
user signed in too long ago, the action fails and throws
FirebaseAuthRecentLoginRequiredException. When this happens,
re-authenticate the user by getting new sign-in credentials from the
user and passing the credentials to reauthenticate. For example:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// Get auth credentials from the user for re-authentication. The example below shows
// email and password credentials but there are multiple possible providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
AuthCredential credential = EmailAuthProvider
.getCredential("user#example.com", "password1234");
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
user.updatePassword(newPass).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Password updated");
} else {
Log.d(TAG, "Error password not updated")
}
}
});
} else {
Log.d(TAG, "Error auth failed")
}
}
});
Changing password in firebase is bit tricky. it's not like what we usually do for changing password in server side scripting and database. to implement change password functionality in your app, first you need to get the user's email from FirebaseAuth or prompt user to input email and after that prompt the user to input old password because you can't retrieve user's password as Frank van Puffelen said. After that you need to reauthenticate that. Once reauthentication is done, if successful, you can use updatePassword(). I have added a sample below that i used for my own app. Hope, it will help you.
private FirebaseUser user;
user = FirebaseAuth.getInstance().getCurrentUser();
final String email = user.getEmail();
AuthCredential credential = EmailAuthProvider.getCredential(email,oldpass);
user.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
user.updatePassword(newPass).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(!task.isSuccessful()){
Snackbar snackbar_fail = Snackbar
.make(coordinatorLayout, "Something went wrong. Please try again later", Snackbar.LENGTH_LONG);
snackbar_fail.show();
}else {
Snackbar snackbar_su = Snackbar
.make(coordinatorLayout, "Password Successfully Modified", Snackbar.LENGTH_LONG);
snackbar_su.show();
}
}
});
}else {
Snackbar snackbar_su = Snackbar
.make(coordinatorLayout, "Authentication Failed", Snackbar.LENGTH_LONG);
snackbar_su.show();
}
}
});
}
}
There is no way to retrieve the current password of a user from Firebase Authentication.
One way to allow your users to change their password is to show a dialog where they enter their current password and the new password they'd like. You then sign in (or re-authenticate) the user with the current passwordand call updatePassword() to update it.
I googled something about resetting Firebase passwords and got to this page. It was helpful but didn't get me all the way to the finish line: I still had to Google around for five or ten minutes. So I'm back to improve the answer for VueJS users.
I see lots of code here using "FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();" in the top line. That's a piece of the puzzle mentioned in the most popular two answers.
But I couldn't get that to work in my project, which is written in VueJS. So I had to go exploring.
What I found was another page of the Firebase documentation. It's the same page people are getting the quoted code from (I think), but with the documentation written for Web instead of Android/Java.
So check out the first link if you're here using VueJS. I think it'll be helpful. "Get the currently signed-in user" might contain the appropriate code for your project. The code I found there says:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
That page I linked up above ("another page") brought me eventually to the "Set a user's password" part of the Web docs. Posters here correctly state that the user must have been authenticated recently to initiate a password update. Try this link for more on re-authenticating users.
"Set a user's password":
// You can set a user's password with the updatePassword method. For example:
var user = firebase.auth().currentUser;
var newPassword = getASecureRandomPassword();
user.updatePassword(newPassword).then(function() {
// Update successful.
}).catch(function(error) {
// An error happened.
});
"Re-authenticate a user"
var user = firebase.auth().currentUser;
var credential;
// Prompt the user to re-provide their sign-in credentials
user.reauthenticateWithCredential(credential).then(function() {
// User re-authenticated.
}).catch(function(error) {
// An error happened.
});
Query revolves around users forgetting their passwords or wishing to reset their passwords via an email letter. Which can be attained by Auth.sendPasswordResetEmail("email#gmail.com");
begin by initializing
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private String DummyEmail = "Dummy#gmail.com"
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null) {
}
}
};
Somewhere else when a user requests to update or reset their passwords simply access the mAuth,
private void PassResetViaEmail(){
if(mAuth != null) {
Log.w(" if Email authenticated", "Recovery Email has been sent to " + DummyEmail);
mAuth.sendPasswordResetEmail(DummyEmail);
} else {
Log.w(" error ", " bad entry ");
}
}
Now, needless to burden yourself querying around your database to find whether the Email exits or not, Firebase mAuth will handle that for you.
Is the Email authenticated? Is it active in your Authentication list? Then send a password-reset Email.
The content will look something like this
the reset link will prompt the following dialog on a new web page
Extra
if you're bit nerved by the reset-template "devised" by Firebase. You can easily access and customize your own letter from the Firebase Console.
Authentication > Email templates > Password reset
A simple approach to handle changing a password is to send a password reset email to the user.
FirebaseAuth.getInstance().sendPasswordResetEmail("user#example.org")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(Activity.this, "Password Reset Email Sent!"), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(Activity.this, task.getException().getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
This is a kotlin solution to the problem I am putting the method here Hope it helps
// The method takes current users email (currentUserEmail), current users old password (oldUserPassword), new users password (newUserPassword) as parameter and change the user password to newUserPassword
private fun fireBasePasswordChange(
currentUserEmail: String,
oldUserPassword: String,
newUserPassword: String
) {
// To re authenticate the user credentials getting current sign in credentials
val credential: AuthCredential =
EmailAuthProvider.getCredential(currentUserEmail, oldUserPassword)
// creating current users instance
val user: FirebaseUser? = FirebaseAuth.getInstance().currentUser
// creating after successfully re authenticating update password will be called else it will provide a toast about the error ( makeToast is a user defined function here for providing a toast to the user)
user?.reauthenticate(credential)?.addOnCompleteListener { task ->
when {
task.isSuccessful -> {
user.updatePassword(newUserPassword).addOnCompleteListener {
if (it.isSuccessful) {
makeToast("Password updated")
// This part is optional
// it is signing out the user from the current status once changing password is successful
// it is changing the activity and going to the sign in page while clearing the backstack so the user cant come to the current state by back pressing
FirebaseAuth.getInstance().signOut()
val i = Intent(activity, SignInActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i)
(activity as Activity?)!!.overridePendingTransition(0, 0)
} else
makeToast("Error password not updated")
}
}
else -> {
makeToast("Incorrect old password")
}
}
}
}
I knew that we can verify the users email with Firebase Auth 3.0. I'm not able to find any documentation regarding email verification on Android. I'm able to find the same for iOS as well as web but not for Android. Any link to the documentation would be helpful.
From the image, it is clear that once the user signs in, he will be intimated regarding that on email to confirm his subscription. I've subscribed myself and also verified in the users section in Auth tab and I am able to see my mail id and firebase generated unique user id. What's missing here is the confirmation email to my email id. Did some one try this or am I too early trying this? Thanks for your help.
Email verification for android is now available in Firebase.
See this release note:
https://firebase.google.com/support/release-notes/android#9.6
Update
Email verification is available in version 9.6 and higher of the Firebase SDK for Android.
Original answer
Email verification is not available for Android yet. Also answered here with more context.
An alternative suggested by the Firebase team
One thing you could do is to add a node to your Firebase Database which contains all email addresses as children. You should make this node only publicly readable (via Firebase security rules).
Then from within your apps, once a user signs up / signs in, you check if the email of that user is on the list, and if not, you sign them out and kick them out of your app (and as a bonus, you could even log the intruder's email address in your database, so you can later check who is trying to access your app).
This will work for initial testing if you know the e-mail ids of the people who are gonna test your app until the e-mail verification makes its way to Android.
Since email verification only works with Email/Password authentication, the best place to send it wold be in the onComplete method of createUserWithEmailAndPassword(...) method, after signup is successful.
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
sendVerificationEmail();
....
The custom sendVerification method is:
public void sendVerificationEmail() {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
user.sendEmailVerification()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(SignUpActivity.this, "Signup successful.
Verification email sent", Toast.LENGTH_SHORT).show();
}
}
});
}
}
You can then check if the user has verified their email anywhere in your app by calling:
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
firebaseUser = firebaseAuth.getCurrentUser();
if (firebaseUser != null ) {
Log.e(TAG, firebaseUser.isEmailVerified() ? "User is signed in and email is verified" : "Email is not verified");
} else {
Log.e(TAG, "onAuthStateChanged:signed_out");
}
}
};