protected void signIn(AuthCredential credential) { mAuth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (!task.isSuccessful()) { Exception exception = task.getException(); if (exception != null) { String errorText; if (exception instanceof FirebaseAuthUserCollisionException) { errorText = getString(R.string.error_user_collision); } else { errorText = exception.toString(); } errorTV.setText(errorText); errorTV.setVisibility(View.VISIBLE); } LoginManager.getInstance().logOut(); } } }); }
@Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { FirebaseUser firebaseUser = task.getResult().getUser(); mActivity.saveCredentialsOrFinish(mSmartLock, firebaseUser, mResponse); } else { if (task.getException() instanceof FirebaseAuthUserCollisionException) { String email = mResponse.getEmail(); if (email != null) { FirebaseAuth auth = mActivity.getAuthHelper().getFirebaseAuth(); ProviderUtils.fetchTopProvider(auth, email) .addOnSuccessListener(new StartWelcomeBackFlow()) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Intent intent = IdpResponse.getErrorCodeIntent(ErrorCodes.UNKNOWN_ERROR); mActivity.finish(Activity.RESULT_CANCELED, intent); } }); return; } } else { Log.e(TAG, "Unexpected exception when signing in with credential " + mResponse.getProviderType() + " unsuccessful. Visit https://console.firebase.google.com to enable it.", task.getException()); } mActivity.getDialogHolder().dismissDialog(); } }
@Test @Config(shadows = {AuthHelperShadow.class}) public void testSignInFailed_withFacebookAlreadyLinked() { AppCompatBase mockActivity = mock(AppCompatBase.class); IdpResponse idpResponse = new IdpResponse.Builder( new User.Builder(GoogleAuthProvider.PROVIDER_ID, TestConstants.EMAIL) .build()) .setToken(TestConstants.TOKEN) .build(); CredentialSignInHandler credentialSignInHandler = new CredentialSignInHandler( mockActivity, null, RC_ACCOUNT_LINK, idpResponse); FlowParameters mockFlowParams = mock(FlowParameters.class); when(mockActivity.getFlowParams()).thenReturn(mockFlowParams); AuthHelper mockAuthHelper = mock(AuthHelper.class); when(mockActivity.getAuthHelper()).thenReturn(mockAuthHelper); AuthHelperShadow.getFirebaseAuth(); // Force static initialization when(mockAuthHelper.getFirebaseAuth()).thenReturn(AuthHelperShadow.getFirebaseAuth()); ProgressDialogHolder mockHolder = mock(ProgressDialogHolder.class); when(mockActivity.getDialogHolder()).thenReturn(mockHolder); // pretend the account has Facebook linked already when(AuthHelperShadow.getFirebaseAuth().fetchProvidersForEmail(TestConstants.EMAIL)).thenReturn( new AutoCompleteTask<ProviderQueryResult>( new FakeProviderQueryResult( Arrays.asList(FacebookAuthProvider.PROVIDER_ID)), true, null)); // pretend there was already an account with this email Task<AuthResult> exceptionTask = Tasks.forException( new FirebaseAuthUserCollisionException(LINKING_ERROR, LINKING_EXPLANATION)); credentialSignInHandler.onComplete(exceptionTask); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class); verify(mockActivity).startActivityForResult(intentCaptor.capture(), intCaptor.capture()); Intent capturedIntent = intentCaptor.getValue(); User capturedUser = User.getUser(capturedIntent); assertEquals(RC_ACCOUNT_LINK, (int) intCaptor.getValue()); assertEquals( WelcomeBackIdpPrompt.class.getName(), capturedIntent.getComponent().getClassName()); assertEquals( TestConstants.EMAIL, capturedUser.getEmail()); assertEquals( FacebookAuthProvider.PROVIDER_ID, capturedUser.getProviderId()); }
@Test @Config(shadows = {AuthHelperShadow.class}) public void testSignInFailed_withPasswordAccountAlreadyLinked() { AppCompatBase mockActivity = mock(AppCompatBase.class); IdpResponse idpResponse = new IdpResponse.Builder( new User.Builder(GoogleAuthProvider.PROVIDER_ID, TestConstants.EMAIL) .build()) .setToken(TestConstants.TOKEN) .build(); CredentialSignInHandler credentialSignInHandler = new CredentialSignInHandler( mockActivity, null, RC_ACCOUNT_LINK, idpResponse); FlowParameters mockFlowParams = mock(FlowParameters.class); when(mockActivity.getFlowParams()).thenReturn(mockFlowParams); AuthHelper mockAuthHelper = mock(AuthHelper.class); when(mockActivity.getAuthHelper()).thenReturn(mockAuthHelper); AuthHelperShadow.getFirebaseAuth(); // Force static initialization when(mockAuthHelper.getFirebaseAuth()).thenReturn(AuthHelperShadow.getFirebaseAuth()); ProgressDialogHolder mockHolder = mock(ProgressDialogHolder.class); when(mockActivity.getDialogHolder()).thenReturn(mockHolder); // pretend there was already an account with this email Task mockTask = mock(Task.class); when(mockTask.getException()).thenReturn( new FirebaseAuthUserCollisionException(LINKING_ERROR, LINKING_EXPLANATION)); // pretend the account has a Password account linked already when(AuthHelperShadow.getFirebaseAuth().fetchProvidersForEmail(TestConstants.EMAIL)).thenReturn( new AutoCompleteTask<ProviderQueryResult>( new FakeProviderQueryResult( Arrays.asList(EmailAuthProvider.PROVIDER_ID)), true, null)); credentialSignInHandler.onComplete(mockTask); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class); verify(mockActivity).startActivityForResult(intentCaptor.capture(), intCaptor.capture()); Intent capturedIntent = intentCaptor.getValue(); assertEquals(RC_ACCOUNT_LINK, (int) intCaptor.getValue()); assertEquals( WelcomeBackPasswordPrompt.class.getName(), capturedIntent.getComponent().getClassName()); assertEquals( TestConstants.EMAIL, IdpResponse.fromResultIntent(capturedIntent).getEmail()); }