How to delete a Firebase user from Android App? - android

I'm trying to code a Delete User method in my Android App, but I have some issues each time I execute it. This method will be executed when a user pushes the Delete account button on an Activity. My apps works with FirebaseUI Auth.
Here is the method:
private void deleteAccount() {
Log.d(TAG, "ingreso a deleteAccount");
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
final FirebaseUser currentUser = firebaseAuth.getCurrentUser();
currentUser.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG,"OK! Works fine!");
startActivity(new Intent(Main3WelcomeActivity.this, Main3Activity.class));
finish();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG,"Ocurrio un error durante la eliminaciĆ³n del usuario", e);
}
});
}
1) When I execute that function a Smart Lock message appears on the screen and the user is signed in again. Here is a screenshot of this message.
2) On other occasions, when the user is logged in for a long time, the function throws an Exception like this:
06-30 00:01:26.672 11152-11152/com.devpicon.android.firebasesamples E/Main3WelcomeActivity: Ocurrio un error durante la eliminaciĆ³n del usuario
com.google.firebase.FirebaseException: An internal error has occured. [ CREDENTIAL_TOO_OLD_LOGIN_AGAIN ]
at com.google.android.gms.internal.zzacq.zzbN(Unknown Source)
at com.google.android.gms.internal.zzacn$zzg.zza(Unknown Source)
at com.google.android.gms.internal.zzacy.zzbO(Unknown Source)
at com.google.android.gms.internal.zzacy$zza.onFailure(Unknown Source)
at com.google.android.gms.internal.zzact$zza.onTransact(Unknown Source)
at android.os.Binder.execTransact(Binder.java:453)
I've read that I have to re-authenticate the user but I'm not sure how to do this when I'm working with Google Sign In.

As per the Firebase documentation can user delete() method to remove user from the Firebase
Before remove the user please reAuthenticate the user.
Sample code
final 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) {
user.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User account deleted.");
}
}
});
}
});
For more details : https://firebase.google.com/docs/auth/android/manage-users#re-authenticate_a_user
If you want to user re Authentication with other singin provider only need to change the Provider for GoogleAuthProvider below is the sample code
GoogleAuthProvider.getCredential(googleIdToken,null);

The answer provided by Ansuita Jr. is very beautifully explained and is correct with just a small problem.
The user gets deleted even without having successful re-authentication.
This is because we use
user.delete()
in the onComplete() method which is always executed.
Therefore, we need to add an if check to check whether the task is successful or not which is mentioned below
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.e("TAG", "onComplete: authentication complete");
user.delete()
.addOnCompleteListener (new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.e("TAG", "User account deleted.");
} else {
Log.e("TAG", "User account deletion unsucessful.");
}
}
});
} else {
Toast.makeText(UserProfileActivity.this, "Authentication failed",
Toast.LENGTH_SHORT).show();
}
}
});

Your delete callback already handles the case of a failure, why do you add addOnFailureListener later?
Try to delete it, this way:
private void deleteAccount() {
Log.d(TAG, "ingreso a deleteAccount");
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
final FirebaseUser currentUser = firebaseAuth.getCurrentUser();
currentUser.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG,"OK! Works fine!");
startActivity(new Intent(Main3WelcomeActivity.this, Main3Activity.class));
finish();
} else {
Log.w(TAG,"Something is wrong!");
}
}
});
}

First of all, you need to store the auth token or the password at the moment your user is logging in. If your app doesn't provide such as Google Sign-in, Facebook Sign-in or others, you just need to store the password.
//If there's any, delete all stored content from this user on Real Time Database.
yourDatabaseReferenceNode.removeValue();
//Getting the user instance.
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
//You need to get here the token you saved at logging-in time.
String token = "userSavedToken";
//You need to get here the password you saved at logging-in time.
String password = "userSavedPassword";
AuthCredential credential;
//This means you didn't have the token because user used like Facebook Sign-in method.
if (token == null) {
credential = EmailAuthProvider.getCredential(user.getEmail(), password);
} else {
//Doesn't matter if it was Facebook Sign-in or others. It will always work using GoogleAuthProvider for whatever the provider.
credential = GoogleAuthProvider.getCredential(token, null);
}
//We have to reauthenticate user because we don't know how long
//it was the sign-in. Calling reauthenticate, will update the
//user login and prevent FirebaseException (CREDENTIAL_TOO_OLD_LOGIN_AGAIN) on user.delete()
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
//Calling delete to remove the user and wait for a result.
user.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
//Ok, user remove
} else {
//Handle the exception
task.getException();
}
}
});
}
});
}

#Android developers:
I faced an issue where the Firebase Auth information was persisting in the device's disk AFTER uninstalling the app. After experimenting and reading about it, I found that setting android:allowBackup="false" and android:fullBackupContent="false" in the Manifest's <application> tag will ensure the identity information is not persisted after the app is uninstalled.
Please note, this kind of persistence was not happening on all Android devices. In fact, it started happening on one of my devices that never had this issue.

If the sign-in method is "Anonymous", you can just call
FirebaseAuth.getInstance().getCurrentUser().delete().addOnCompleteListener(task -> {
if (task.isSuccessful()){
Log.d(TAG, "Deletion Success");
}
});
But if it's a different method, you will need a re-authentication.
How to re-authenticate

Use this methods :-
remove()
is equivalent to calling set(null).
or
removeUser()
removeUser(credentials, [onComplete])

Only get current user and delete it by using following method it'll work fine
user.delete();
and you can add on Oncompletelistner also
by addinduser.delete().addOnCompleteListner(new OnCompleteListner)and more on

If you are using AuthUI or FirebaseAuth you can just do the following
AuthUI.getInstance().delete(context).addOnSuccessListener {
}.addOnFailureListener{
}
OR
FirebaseAuth.getInstance().currentUser.delete().addOnSuccessListener...

If you are using FirebaseUI Auth you can just do the following
private void delete() {
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
FirebaseUser user=firebaseAuth.getCurrentUser();
user.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
startActivity(new Intent(Main3WelcomeActivity.this, Main3Activity.class));
finish();
Toast.makeText(Main3WelcomeActivity.this,"Account deleted",Toast.LENGTH_LONG).show();
}else {
Toast.makeText(Home.this,"failed",Toast.LENGTH_LONG).show();
}
}
});}

Related

FireBase Auth createUserWithEmailAndPassword().then() not working

I am working on an android application that involves user firebase auth for user sign up. The sign up works but I want to add username to database by implementing it in .then() but my android studio keeps giving "unresolved method then(?)". I am also using catch but that seems to work fine.The code I am writing is as following where firebaseAuth is an object of type FirebaseAuth:
firebaseAuth.createUserWithEmailAndPassword(email,password)
.then( (u) => {
//Implementation of then
})
.catch(error => {
switch (error.code) {
case 'auth/email-already-in-use':
EmailWarning.setText("Email already in use");
case 'auth/invalid-email':
EmailWarning.setText("Invalid Email");
case 'auth/weak-password':
PasswordWarning.setText("Password should be 8 characters or longer");
default:
PasswordWarning.setText("Error during sign up");
}
});
I found a similar problem in following link but even after trying this, it's not working.
I looked further into the firebase documentation and found another implementation which uses on complete listener here however the error codes described in this documentation doesn't seem to work with it.
Update 1:
I ended up implementing on complete listener as following:
firebaseAuth.createUserWithEmailAndPassword(email,password)
.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
FirebaseUser user = firebaseAuth.getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(Username)
.build();
user.updateProfile(profileUpdates);
}
else {
// If sign up fails, display a message to the user.
switch (task.getException()) {
case "auth/email-already-in-use":
EmailWarning.setText("Email already in use");
case "auth/invalid-email":
EmailWarning.setText("Invalid Email");
case "auth/weak-password":
PasswordWarning.setText("Password should be 8 characters or longer");
default:
PasswordWarning.setText("Error during sign up");
}
}
}
});
Now the user adding part works fine but the exception handler doesn't work with strings so I can't find a way to work with error codes given on firebase documentation
I wasn't able to find a solution to .then() issue but after searching more into getExceptions() I found a solution at this link. Now my current implementation looks as following:
firebaseAuth.createUserWithEmailAndPassword(email,password)
.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
FirebaseUser user = firebaseAuth.getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(Username)
.build();
user.updateProfile(profileUpdates);
OpenApp();
}
else {
// If sign up fails, display a message to the user.
String errorCode = ((FirebaseAuthException) task.getException()).getErrorCode();
if (task.getException() instanceof FirebaseAuthUserCollisionException)
EmailWarning.setText("Email already in use");
else if(task.getException() instanceof FirebaseAuthInvalidCredentialsException)
EmailWarning.setText("Invalid Email");
else if(task.getException() instanceof FirebaseAuthWeakPasswordException)
PasswordWarning.setText("Password should be 8 characters or longer");
else
PasswordWarning.setText("Error during sign up");
}
}
});
Also found another alternate implementation by try catch and and getException().getErrorCode() here.
I found this in the docs for you:
firebaseAuth.createUserWithEmailAndPassword(email, password)
.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, "createUserWithEmail:success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(EmailPasswordActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
// ...
}
});
Looks like you need to use .addOnCompleteListener
Doc -> https://firebase.google.com/docs/auth/android/password-auth
I have found my issue with the help of (task.getException())
So I hope maybe it will helpful for resolving your issue.
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
} else {
Log.d("---->",""+task.getException());
}
}
});

How to check whether a user is authenticated or not in Firebase?

I have a few sign-up methods in my app as shown below:
Let's revolve the problem around Google sign-in method:
What I am doing is that when a user signs in enteringDataIntoUserNode() method is called inside signInWithCredential() method like:
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
AuthCredential credential =
GoogleAuthProvider.getCredential(acct.getIdToken(), null);
// signing in
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// entering default values in the database
enteringDataIntoUserNode();
Intent intent = new Intent(LoginAndSignupActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
else {
Log.w(TAG, "signInWithCredential:failure", task.getException());
}
}
});
}
enteringDataIntoUserNode()
private void enteringDataIntoUserNode() {
final String currentUid = mAuth.getCurrentUser().getUid();
//
String deviceToken = FirebaseInstanceId.getInstance().getToken();
final String userName = mAuth.getCurrentUser().getDisplayName();
String imageUrl = mAuth.getCurrentUser().getPhotoUrl().toString();
String userStatus = "Hi there! How is it going?";
// inserting data in key-value pair
usersReference.child(currentUid).child("user_name").setValue(userName);
usersReference.child(currentUid).child("user_status").setValue(userStatus);
usersReference.child(currentUid).child("user_image").setValue(imageUrl);
usersReference.child(currentUid).child("device_token").setValue(deviceToken);
// when this last value will be inserted then, making an intent to MainActivity
usersReference.child(currentUid).child("user_thumb_image").setValue(imageUrl)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Log.d(TAG, "onComplete: Data insertion for the new user is successful ");
}
}
});
}
enteringDataIntoUserNode() method is simply passing some default data to the database every time a user signs in. But if a user change its details like image or username etc. and sign out and again sign in through Google sign in method then again enteringDataIntoUserNode() method will be called and user details would be overwritten with the default ones.
My question is that is there any way to check whether a user is signing in for the first time or not during the Google sign in so that in the latter case I can skip calling enteringDataIntoUserNode() method and prevent overwriting of data.
Same thing I want to acheive during Facebook and Phone Number sign in.
If you check if the user logs in for the first time, it's the same thing if you want to check if a user is new. So to solve this, we can simply call the isNewUser() method in the OnCompleteListener.onComplete callback like this:
OnCompleteListener<AuthResult> completeListener = new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
boolean isNewUser = task.getResult().getAdditionalUserInfo().isNewUser();
if (isNewUser) {
Log.d("TAG", "The user is new!");
} else {
Log.d("TAG", "The user is not new!");
}
}
}
};
For more informations, please see the official documentation.
You could check when the account was created with:
task.getResult().getUser().getMetadata().getCreationTimestamp()
See the reference docs.
But a common approach is also to check if the user already exists in the database using a transaction.

Email not being Verified in Firebase

I am using Firebase's isEmailVerified method to verify an email. The following is the code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verifying);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
mAuth=FirebaseAuth.getInstance();
spinner=(ProgressBar)findViewById(R.id.progressBar);
spinner.setVisibility(View.GONE);
Log.e("I am launched","hello");
if(user.isEmailVerified()==true){
Log.e("I am here","hello");
State state= new AccountSettingUp(this);
state.doAction();
} else {
Log.e("Maybe i am here","yes");
user.sendEmailVerification()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d("email", "Email sent.");
}
}
});
}
Here, the else code should only run when the email is not verified. However, even after I verify the email and restart the activity, the if statement is not true and the email is sent again.
This behavior appears to be a limitation, possibly a bug, in the current version (10.0.1) of Firebase Authentication. The same issue is reported in this related question.
I tried doing a reload() of the user data after the email verification. That didn't help. As reported in the related question, it seems that a sign-out/sign-in is required to get the new email verification status.
For firebase-auth:10.0.1, it seems that it is not possible. However, the workaround is to log the user out and logging them in again. Upon signing in, the isEmailVerified() function will work properly.
I did a sign up activity
mAuth.createUserWithEmailAndPassword(Email, Password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
user = mAuth.getCurrentUser();
UserProfileChangeRequest profileChange = new UserProfileChangeRequest.Builder()
.setDisplayName(FirstName)
.build();
user.updateProfile(profileChange).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(getBaseContext(), "Thanks for signing up, " + FirstName + "! Please verify your email!", Toast.LENGTH_SHORT).show();
user.sendEmailVerification();
mAuth.signOut();
Intent a = new Intent(getBaseContext(),Login_Activity.class);
startActivity(a);
}
else {
Toast.makeText(getBaseContext(),"Failed to create username",Toast.LENGTH_SHORT).show();
}
}
});
}
else{
Toast.makeText(getBaseContext(),"Failed",Toast.LENGTH_SHORT).show();
}
}
});
As seen in the 'task.isSuccessful()' portion of the '.updateProfile' code, I did an 'mAuth.signOut();' and informing them to verify their email before sending them back to the login screen.
On the Login screen, I did a simple 'if (user.isEmailVerified())' statement to check for verification. If they are still not verified, a toast will appear to remind them, if they are verified then they will proceed into the next activity.
Hope this helps!

How to send verification email with Firebase?

I am signing up my users using Firebase's email and password method. like this:
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseUser signed = task.getResult().getUser();
writeNewUser(signed.getUid());
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
updateUser(b);
}
}, 3000);
} else {
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
onSignupFailed();
}
}, 3000);
}
}
});
After the user's email has been successfully registered, I would like Firebase to send a verification email. I know this is possible using Firebase's sendEmailVerification. In addition to sending this email, I want the user's account to be disabled until they verify the email. This would also require using Firebase's isEmailVerified feature. However, I have been unsuccessful in getting Firebase to send the verification email, I have not been able to figure out to get it to disable and enable the account sending the verification email and after it has been verified.
This question is about how to use Firebase to send the verification email. The OP is unable to figure out how to disable and enable the account sending the verification email and after it has been verified.
Also, this is not properly documented in the firebase documentation. So I am writing a step by step procedure that someone may follow if he/she is facing the problem.
1) User can use createUserWithEmailAndPassword method.
Example:
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.d("TAG", "createUserWithEmail:onComplete:" + task.isSuccessful());
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
// Show the message task.getException()
}
else
{
// successfully account created
// now the AuthStateListener runs the onAuthStateChanged callback
}
// ...
}
});
If the new account was created, the user is also signed in, and the AuthStateListener runs the onAuthStateChanged callback. In the callback, you can manage the work of sending the verification email to the user.
Example:
onCreate(...//
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
// NOTE: this Activity should get onpen only when the user is not signed in, otherwise
// the user will receive another verification email.
sendVerificationEmail();
} else {
// User is signed out
}
// ...
}
};
Now the send verification email can be written like:
private void sendVerificationEmail()
{
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.sendEmailVerification()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
// email sent
// after email is sent just logout the user and finish this activity
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(SignupActivity.this, LoginActivity.class));
finish();
}
else
{
// email not sent, so display message and restart the activity or do whatever you wish to do
//restart this activity
overridePendingTransition(0, 0);
finish();
overridePendingTransition(0, 0);
startActivity(getIntent());
}
}
});
}
Now coming to LoginActivity:
Here if the user is successfully logged in then we can simply call a method where you are writing logic for checking if the email is verified or not.
Example:
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
//Log.d("TAG", "signInWithEmail:onComplete:" + task.isSuccessful());
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
//Log.w("TAG", "signInWithEmail:failed", task.getException());
} else {
checkIfEmailVerified();
}
// ...
}
});
Now consider the checkIfEmailVerified method:
private void checkIfEmailVerified()
{
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user.isEmailVerified())
{
// user is verified, so you can finish this activity or send user to activity which you want.
finish();
Toast.makeText(LoginActivity.this, "Successfully logged in", Toast.LENGTH_SHORT).show();
}
else
{
// email is not verified, so just prompt the message to the user and restart this activity.
// NOTE: don't forget to log out the user.
FirebaseAuth.getInstance().signOut();
//restart this activity
}
}
So here I m checking if the email is verified or not. If not, then log out the user.
So this was my approach to keeping track of things properly.
send verification to user's Email
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.sendEmailVerification();
check if user is verified
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
boolean emailVerified = user.isEmailVerified();
Use FirebaseAuth.getInstance().getCurrentUser().sendEmailVerification() and FirebaseAuth.getInstance().getCurrentUser().isEmailVerified()
There is no way to disable the account via the Firebase SDK. The thing you can do is use the GetTokenResult containing the Firebase Auth ID Token and validate it against your custom backend or set a flag to Firebase database corresponding to that user. Personally I'd go with the flag in the Firebase database
For sending email link with Firebase first you need to grab FirebaseAuth instance
using the instance we create user on Firebase through:
firebaseauth.createUserWithEmailAndPassword(email,pass);
When method return success we send verification link to user using Firebase user instance as follows:
final FirebaseUser user = mAuth.getCurrentUser();
user.sendEmailVerification()
See this link: https://technicalguidee.000webhostapp.com/2018/10/email-verification-through-link-using-firebase-authentication-product-android.
mAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
mAuth.getCurrentUser().sendEmailVerification().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(this, "please check email for verification.", Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}else{
Toast.makeText(this, task.getException().getMessage() , Toast.LENGTH_SHORT).show();
}
}
});
For Kotlin
val user: FirebaseUser? = firebaseAuth.currentUser
user?.sendEmailVerification()

How to link Multiple Auth Providers to an Firebase Account on Android?

I referenced the documentation in Firebase page. My problem is in this paragraph:
The call to linkWithCredential will fail if the credentials are already linked to another user account. In this situation, you must handle merging the accounts and associated data as appropriate for your app:
FirebaseUser prevUser = currentUser; currentUser = auth.signInWithCredential(credential).await().getUser(); // Merge
prevUser and currentUser accounts and data // ...
I can't figure out how to add this code into my project. When and where do I put this code
auth.signInWithCredential(credential).await().getUser();
into my java file? Android Studio announced me that it can't resolve await() method.
What should I do to resolve that problem. Thank you in advance!
You should handle this part of code when the linkWithCredentials call fails.
Here is a small example :
mAuth.getCurrentUser().linkWithCredential(credentials).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
FirebaseUser prevUser = currentUser;
try {
currentUser = Tasks.await(auth.signInWithCredential(credential)).getUser();
} catch (Exception e) {
e.printStackStrace();
}
// Merge prevUser and currentUser accounts and data
// ...
} else {
}
}
});
NB: Task.await() doesn't exist anymore you should use Tasks.await(...) static method instead.
Suppose that:
One account per email address setting is enabled on firebase authentication
User are logging in with anonymous authentication
The linkWithCredential usually fails with FirebaseAuthUserCollisionException, it could happen either because this credential is used to login before (you can check by searching this email on firebase console) or this email account is used to login before but with different providers ( such as a user logged in with abc#gmail.com by using google sign in before, now he/she uses abc#gmail.com but with Facebook login ) To handle it, you need 2 steps:
Step 1: link with anonymous account
private void linkWithAnonymousAccount(final AuthCredential credential) {
mFirebaseAuth.getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
getFirebaseToken();
} else {
Exception exception = task.getException();
if (exception instanceof FirebaseAuthUserCollisionException) {
signInWithFirebase(credential);
} else {
Utils.showDialogMessage(mContext, task.getException().getLocalizedMessage());
}
}
}
});
}
Step 2: sign with firebase
private void signInWithFirebase(AuthCredential credential) {
mFirebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
getFirebaseToken();
} else {
Utils.showDialogMessage(mContext, task.getException().getLocalizedMessage());
}
}
});
}
Google says the step 2 is merging because after signed in, you need to get information of the previous user and put into the new user.
I hope it helpful.

Categories

Resources