public void startSignIn()

in auth/src/main/java/com/firebase/ui/auth/viewmodel/idp/LinkingSocialProviderResponseHandler.java [44:123]


    public void startSignIn(@NonNull final IdpResponse response) {
        if (!response.isSuccessful()) {
            setResult(Resource.forFailure(response.getError()));
            return;
        }
        if (isInvalidProvider(response.getProviderType())) {
            throw new IllegalStateException(
                    "This handler cannot be used to link email or phone providers.");
        }
        if (mEmail != null && !mEmail.equals(response.getEmail())) {
            setResult(Resource.forFailure(new FirebaseUiException
                    (ErrorCodes.EMAIL_MISMATCH_ERROR)));
            return;
        }

        setResult(Resource.forLoading());

        // The Generic IDP flow does not return a credential - it signs us in right away.
        // If the user was prompted to sign-in via Generic IDP, we can link immediately.
        // Example: Existing user with Yahoo provider - signs in with microsoft -
        // prompted to sign in with yahoo. Sign in with Yahoo will be succesful, it won't
        // return a credential.
        if (isGenericIdpLinkingFlow(response.getProviderType())) {
            getAuth().getCurrentUser()
                    .linkWithCredential(mRequestedSignInCredential)
                    .addOnSuccessListener(authResult -> handleSuccess(response, authResult))
                    .addOnFailureListener(e -> Resource.<IdpResponse>forFailure(e));
            return;
        }

        final AuthOperationManager authOperationManager = AuthOperationManager.getInstance();
        final AuthCredential credential = ProviderUtils.getAuthCredential(response);

        if (authOperationManager.canUpgradeAnonymous(getAuth(), getArguments())) {
            if (mRequestedSignInCredential == null) {
                // The user has provided a valid credential by signing in with a federated
                // idp. linkWithCredential will fail because the user is anonymous and the account
                // exists (we're in the welcome back flow).
                // We know that they are signing in with the same IDP because requestSignInCredential
                // is null.
                // We just need to have the developer handle the merge failure.
                handleMergeFailure(credential);
            } else {
                // The user has logged in with an IDP that has the same email with another IDP
                // present on the account.
                // These IDPs belong to the same account - they must be linked, but we can't lose
                // our anonymous user session
                authOperationManager.safeLink(credential, mRequestedSignInCredential, getArguments())
                        .addOnSuccessListener(result -> handleMergeFailure(credential))
                        .addOnFailureListener(e -> setResult(Resource.forFailure(e)));
            }
        } else {
            getAuth().signInWithCredential(credential)
                    .continueWithTask(task -> {
                        final AuthResult result = task.getResult();
                        if (mRequestedSignInCredential == null) {
                            return Tasks.forResult(result);
                        } else {
                            return result.getUser()
                                    .linkWithCredential(mRequestedSignInCredential)
                                    .continueWith(task1 -> {
                                        if (task1.isSuccessful()) {
                                            return task1.getResult();
                                        } else {
                                            // Since we've already signed in, it's too late
                                            // to backtrack so we just ignore any errors.
                                            return result;
                                        }
                                    });
                        }
                    })
                    .addOnCompleteListener(task -> {
                        if (task.isSuccessful()) {
                            handleSuccess(response, task.getResult());
                        } else {
                            setResult(Resource.forFailure(task.getException()));
                        }
                    });
        }
    }