Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FirebaseAuthUserCollisionException?

I am using the firebase documentation to use Facebook login my android application. I am successfully able to login users using Google and Twitter. But when i click on Login with Facebook, the button is changing to Logout button. Actually it should redirect to Login success activity, because i configured FirebaseAuth.AuthStateListener.

I am posting the Activity here, Please let me know if i am doing anything wrong.

public class MainActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "MainActivity";
    private static final int GOOGLE_RC_SIGN_IN = 9001;
    private static final int TWITTER_RC_SIGN_IN = 140;

    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthStateListener;

    private GoogleApiClient mGoogleApiClient;
    CallbackManager callbackManager;
    @BindView(R.id.google_signin_button) SignInButton mGoogleSigninButton;
    @BindView(R.id.facebook_login_button) LoginButton mFacebookLoginButton;
    @BindView(R.id.twitter_login_button) TwitterLoginButton mTwitterLoginButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TwitterAuthConfig authConfig = new TwitterAuthConfig(getString(R.string.twitter_consumer_key), getString(R.string.twitter_consumer_secret));
        Fabric.with(this, new Twitter(authConfig));
        FacebookSdk.sdkInitialize(this);
        setContentView(R.layout.activity_main);

        ButterKnife.bind(MainActivity.this);

        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this,this)
                .addApi(Auth.GOOGLE_SIGN_IN_API,gso)
                .build();

        mAuth = FirebaseAuth.getInstance();
        mAuthStateListener = new FirebaseAuth.AuthStateListener(){
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if (user != null) {
                    //User is signed in
                    Log.v(TAG, "Yo Baby");
                    Log.d(TAG,"name"+user.getDisplayName());
                    goToHome();
                } else {
                    //Do some logic
                }
            }
        };

        mGoogleSigninButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent signinIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
                startActivityForResult(signinIntent, GOOGLE_RC_SIGN_IN);
            }
        });

        callbackManager = CallbackManager.Factory.create();
        mFacebookLoginButton.setReadPermissions("email", "public_profile");
        mFacebookLoginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                handleFacebookAuthentication(loginResult.getAccessToken());
            }

            @Override
            public void onCancel() {

            }

            @Override
            public void onError(FacebookException error) {

            }
        });

        mTwitterLoginButton.setCallback(new Callback<TwitterSession>() {
            @Override
            public void success(Result<TwitterSession> result) {
                handleTwitterAuthentication(result.data);
            }

            @Override
            public void failure(TwitterException exception) {

            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == GOOGLE_RC_SIGN_IN){
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            if (result.isSuccess()) {
                GoogleSignInAccount account = result.getSignInAccount();
                handleGoogleAuthentication(account);
            } else {
                //Google Login Failed
            }
        } else if (requestCode == TWITTER_RC_SIGN_IN) {
            mTwitterLoginButton.onActivityResult(requestCode,resultCode,data);
        } else {
            callbackManager.onActivityResult(requestCode,resultCode,data);
        }
    }

    private void handleGoogleAuthentication(GoogleSignInAccount account) {
        AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
        mAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    //Save Credentials in Google Smart Lock
                } else {
                    //
                }
            }
        });
    }

    private void handleFacebookAuthentication(AccessToken accessToken) {
        AuthCredential credential = FacebookAuthProvider.getCredential(accessToken.getToken());
        mAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    //Save Credentials in Google Smart Lock
                } else {

                }
            }
        });
    }

    private void handleTwitterAuthentication(TwitterSession session) {
        AuthCredential credential = TwitterAuthProvider.getCredential(session.getAuthToken().token, session.getAuthToken().secret);
        mAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    //Save credentials in Google Smart lock
                } else {

                }
            }
        });
    }
    private void goToHome() {
        startActivity(new Intent(MainActivity.this, HomeActivity.class));
        finish();
        return;
    }

    @Override
    protected void onStart() {
        super.onStart();
        mAuth.addAuthStateListener(mAuthStateListener);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mAuthStateListener != null) {
            mAuth.removeAuthStateListener(mAuthStateListener);
        }
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }
}

Update1

Finally I understood the reason why Facebook login is not working. This is because i already logged into the app using Google Signin. Since my email for Google and Facebook are same it is giving FirebaseAuthUserCollisionException. I should have Debugged the application before i post the question in Stackoverflow.

Update2

I am not closing this question as it may help someone who faced the situation like me. And I will also update the solution for FirebaseAuthUserCollisionException, as i dig more into it.

like image 204
Raju Avatar asked Jun 11 '16 12:06

Raju


1 Answers

I faced the same problem and this is how I got around with.
If the task is not successful, I'm checking whether the exception thrown is an instanceof FirebaseAuthUserCollisionException. If yes, a toast is displayed to the user saying 'Account with email already exists!'.

private void handleFacebookAccessToken(final AccessToken token) {
    Log.d(TAG, "handleFacebookAccessToken:" + token);

    AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {

                    if (!task.isSuccessful()) {
                        Log.w(TAG, "signInWithCredential", task.getException());
                        Toast.makeText(getApplicationContext(), "Firebase Facebook login failed",
                                Toast.LENGTH_SHORT).show();

                        if(task.getException() instanceof FirebaseAuthUserCollisionException) {
                            Toast.makeText(getApplicationContext(), "User with Email id already exists",
                                    Toast.LENGTH_SHORT).show();
                        }
                        LoginManager.getInstance().logOut();
                    }
                }
            });
}  

Credit: Check if given email exists

like image 179
Nishanth Sreedhara Avatar answered Oct 19 '22 23:10

Nishanth Sreedhara