How to handle FirebaseAuthUserCollisionException

后端 未结 2 1644
自闭症患者
自闭症患者 2020-12-30 10:30

I started getting a FirebaseAuthUserCollisionException exception when I try to sign in with Facebook in my Android application

相关标签:
2条回答
  • 2020-12-30 11:01

    You will get that error when the user had previously signed in with the same email using a different provider. For example, the user signs in with email user@gmail.com using Google. The user then tries to sign in with the same email but using Facebook. The Firebase Auth backend will return that error (account exists with different credential). In that case, you should use the fetchProvidersForEmail to look up the existing providers associated with email user@gmail.com, in this case google.com. You signInWithCredential to the existing google account to prove ownership of that account, and then linkWithCredential the Facebook credential the user originally was trying to sign in with. This merges both accounts so in the future the user can sign in with either.

    This happens when you use the single accounts per email. If you want to allow different accounts per email, you can switch to multiple accounts per email in the Firebase console.

    Here is an example:

    mAuth.signInWithCredential(authCredential)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                // Account exists with different credential. Assume the developer wants to
                // continue and link new credential to existing account.
                if (!task.isSuccessful() &&
                    task.getException() instanceof FirebaseAuthUserCollisionException) {
                    FirebaseAuthUserCollisionException exception =
                            (FirebaseAuthUserCollisionException)task.getException();
                    if (exception.getErrorCode() == 
                        ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL) {
                        // Lookup existing account’s provider ID.
                        mAuth.fetchProvidersForEmail(existingAcctEmail)
                           .addOnCompleteListener(new OnCompleteListener<ProviderQueryResult> {
                              @Override
                              public void onComplete(@NonNull Task<ProviderQueryResult> task) {
                                if (task.isSuccessful()) {
                                  if (task.getResult().getProviders().contains(
                                          EmailAuthProvider.PROVIDER_ID)) {
                                    // Password account already exists with the same email.
                                    // Ask user to provide password associated with that account.
                                    ... 
                                    // Sign in with email and the provided password.
                                    // If this was a Google account, call signInWithCredential instead.
                                    mAuth.signInWithEmailAndPassword(existingAcctEmail, password)
                                      addOnCompleteListener(new OnCompleteListener<AuthResult> {
                                        @Override
                                        public void onComplete(@NonNull Task<AuthResult> task) {
                                          if (task.isSuccessful()) { 
                                            // Link initial credential to existing account.
                                            mAuth.getCurrentUser().linkWithCredential(authCredential);
                                          }
                                        }
                                      });
                                  }
                                }
                              }
                            });
                }
            }
        });
    
    0 讨论(0)
  • 2020-12-30 11:05

    There is no need for this, you can just allow multiple accounts merge under firebaase->authentication-> sign in method -> Advanced - > change (multiple accounts per email address.

    Firebase will merge the same email address but will give you different user UID.

    See sample below.

    AuthCredential authCredential =  FacebookAuthProvider.getCredential(token.getToken());
        
        mAuth.signInWithCredential(authCredential)
                .addOnCompleteListener(this, task -> {
                    if (task.isSuccessful()) {
                        // Sign in success, update UI with the signed-in user's information
                        Log.d(TAG, "signInWithCredential:success");
                        FirebaseUser user = mAuth.getCurrentUser();
                        LoginFacebookGoogleActivity.this.updateUI(user);
                    } else {
                        // If sign in fails, display a message to the user.
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
    
                        if(task.getException() instanceof FirebaseAuthUserCollisionException){
                            FirebaseAuthUserCollisionException exception = (FirebaseAuthUserCollisionException) task.getException();
    
                            //log this bundle into the analytics to analyze which details you want to collect
                            
                        }
    
                        Toast.makeText(LoginFacebookGoogleActivity.this, "Authentication failed " + task.getException(), Toast.LENGTH_SHORT).show();
                        LoginFacebookGoogleActivity.this.updateUI(null);
                    }
                });
    
    0 讨论(0)
提交回复
热议问题