3

나는 Facebook을 내 앱에 통합하기 위해 this Firebase 튜토리얼을 팔로우하고 있습니다.Firebase를 사용하여 Android에서 Facebook 로그인

com.google.firebase.auth.FirebaseAuthUserCollisionException : 계정이 이미 동일한 이메일 주소 만 다른 로그인 자격 증명을 사용하여 존재하는 모든 것은 내가이 예외를 데 있다는 사실을 제외하고 좋아 보인다. 이 이메일 주소와 연결된 제공 업체를 사용하여 로그인하십시오.

이것이 정확히 내가하려는 일이라고 생각하면 충분합니다. 먼저 gmail을 내 앱에 통합하는 코드를 작성하고 내 이메일 계정을 사용하여 로그인했습니다. 그런 다음 Facebook에 로그인하여 오류가 발생했습니다.

는이 문제를 해결하는 방법, 난 이미 자격에 의해 주장 이메일 주소로 계정이 존재하는 경우

FirebaseAuthUserCollisionException가 던진 것을 here을 발견하여 검색을. 이 문제를 해결하려면 fetchProvidersForEmail (String)을 호출 한 다음 사용자 중 하나를 사용하여 로그인하도록 요청하십시오.

마지막 문제는 내 작업 (코드의 마지막 블록을 확인) 성공하지 않을 때문에, 나는 제대로 fetchProvidersForEmail 방법을 사용하고 잘 모르겠어요 것입니다.

누구든지 지원할 수 있습니까? 감사합니다,

* 아래 코드는 현재 gmail 및 Facebook의 로그인을 지원하고 있습니다. 내가 여기서 말하는 방법은 마지막 것, handleFacebookAccessToken입니다.

public class SignInActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener { 

/** 
* References 
* https://developers.google.com/identity/sign-in/android/sign-in#configure_google_sign-in_and_the_googleapiclient_object 
*/ 

// Here a simple Sign-In button is used to initiate authentication. In this step you will 
// implement the logic to Sign-In with Google then use that Google account to authenticate with 
// Firebase. 

private static final String TAG = "SignInActivity"; 
private static final int RC_SIGN_IN = 9001; 
private GoogleApiClient mGoogleApiClient; 
private FirebaseAuth mAuth; 

private FirebaseAuth.AuthStateListener mAuthListener; 

LoginButton facebookLogin; 
CallbackManager cM; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    FacebookSdk.sdkInitialize(this.getApplicationContext()); 
    setContentView(R.layout.activity_sign_in); 

    cM = CallbackManager.Factory.create(); 
    facebookLogin = (LoginButton) findViewById(R.id.sign_in_button_facebook); 
    if (facebookLogin != null) { 
     facebookLogin.setReadPermissions("public_profile", "email", "user_friends"); 
     facebookLogin.registerCallback(cM, new FacebookCallback<LoginResult>() { 
      @Override 
      public void onSuccess(LoginResult loginResult) { 
       Log.d(TAG, "facebook:onSuccess:" + loginResult); 
       handleFacebookAccessToken(loginResult.getAccessToken()); 
      } 

      @Override 
      public void onCancel() { 
       Log.d(TAG, "facebook:onCancel"); 
       // ... 
      } 

      @Override 
      public void onError(FacebookException error) { 
       Log.d(TAG, "facebook:onError", error); 
       // ... 
      } 
     }); 
    } 

    // Configure Google Sign-In to request the user data required by the app. For example, to 
    // configure Google Sign-In to request users' ID and basic profile information, create a 
    // GoogleSignInOptions object with the DEFAULT_SIGN_IN parameter (ID and basic profile are 
    // included in DEFAULT_SIGN_IN). To request users' email addresses as well, create the 
    // GoogleSignInOptions object with the requestEmail option. 
    GoogleSignInOptions mGoogleSignInOptions = new GoogleSignInOptions 
      .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
      .requestIdToken(getString(R.string.default_web_client_id)) 
      .requestEmail() 
      .build(); 

    // Create a GoogleApiClient object with access to the Google Sign-In API and the options 
    // specified. Note: To use enableAutoManage, your activity must extend FragmentActivity or 
    // AppCompatActivity (a subclass of FragmentActivity), both of which are part of the Android 
    // Support Library. You can use GoogleApiClient in a Fragment; however, the fragment's 
    // parent activity must be a FragmentActivity. If you can't extend FragmentActivity, you 
    // must manually manage the GoogleApiClient connection lifecycle. 
    mGoogleApiClient = new GoogleApiClient 
      .Builder(this) 
      .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) 
      .addApi(Auth.GOOGLE_SIGN_IN_API, mGoogleSignInOptions) 
      .build(); 

    // Configure the sign in button. 
    SignInButton mSignInButton = (SignInButton) findViewById(R.id.sign_in_button); 
    if (mSignInButton != null) { 
     mSignInButton.setSize(SignInButton.SIZE_STANDARD); 
     mSignInButton.setOnClickListener(this); 
    } 

    // Initialize FirebaseAuth 
    mAuth = FirebaseAuth.getInstance(); 

    mAuthListener = new FirebaseAuth.AuthStateListener() { 
     @Override 
     public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 
      FirebaseUser user = firebaseAuth.getCurrentUser(); 
      if (user != null) { 
       // User is signed in 
       Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); 
      } else { 
       // User is signed out 
       Log.d(TAG, "onAuthStateChanged:signed_out"); 
      } 
      // ... 
     } 
    }; 
} 

@Override 
public void onClick(View v) { 
    switch (v.getId()) { 
     case R.id.sign_in_button: 
      signIn(); 
      break; 
    } 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    mAuth.addAuthStateListener(mAuthListener); 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    if (mAuthListener != null) { 
     mAuth.removeAuthStateListener(mAuthListener); 
    } 
} 

// Handle sign-in button taps by creating a sign-in intent with the getSignInIntent method, and 
// starting the intent with startActivityForResult. Starting the intent prompts the user to 
// select a Google account to sign in with. If you requested scopes beyond profile, email, and 
// openid, the user is also prompted to grant access to the requested resources. 
private void signIn() { 
    Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); 
    startActivityForResult(signInIntent, RC_SIGN_IN); 
} 

// An unresolvable error has occurred and Google APIs (including Sign-In) will not be available. 
@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
    Log.d(TAG, "onConnectionFailed:" + connectionResult); 
    Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show(); 
} 

// Handle the result of the Google Sign In in the activity's onActivityResult method, which 
// retrieve the sign-in result with getSignInResultFromIntent. 
@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 

    cM.onActivityResult(requestCode, resultCode, data); 

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); 
    if (requestCode == RC_SIGN_IN) { 
     GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); 
     handleSignInResult(result); 
    } 
} 

// After you retrieve the sign-in result, you can check if sign-in succeeded with the isSuccess 
// method. If sign-in succeeded, you can call the getSignInAccount method to get a 
// GoogleSignInAccount object that contains information about the signed-in user, such as the 
// user's name. You can also get the user's email address with getEmail, the user's Google ID 
// (for client-side use) with getId, and an ID token for the user with with getIdToken. If you 
// need to pass the currently signed-in user to a backend server, send the ID token to your 
// backend server and validate the token on the server. 
public void handleSignInResult(GoogleSignInResult result) { 
    if (result.isSuccess()) { 
     GoogleSignInAccount account = result.getSignInAccount(); 

     // Google Sign In was successful, authenticate with Firebase. 
     firebaseAuthWithGoogle(account); 

    } else { 
     // Google Sign In failed 
     // TODO: 26/06/2016 Handle no internet connection 
     Log.e(TAG, "Google Sign In failed."); 
    } 
} 

// Add the required firebaseAuthWithGoogle method to authenticate with the signed in Google 
// account. 
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) { 
    Log.d(TAG, "firebaseAuthWithGooogle:" + acct.getId()); 

    AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null); 
    mAuth 
      .signInWithCredential(credential) 
      .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { 
       @Override 
       public void onComplete(@NonNull Task<AuthResult> task) { 
        Log.d(TAG, "signInWithCredential: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, "signInWithCredential", task.getException()); 
         Toast.makeText(SignInActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show(); 

        } else { 
         startActivity(new Intent(SignInActivity.this, MainActivity.class)); 
         finish(); 
        } 
       } 
      }); 
} 

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

    // This commented block below is what is on the tutorial, but gives the exceptio explained. 
    /* 
    AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken()); 
    mAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { 
     @Override 
     public void onComplete(@NonNull Task<AuthResult> task) { 
      Log.d(TAG, "signInWithCredential: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, "signInWithCredential", task.getException()); 
       Toast.makeText(SignInActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show(); 
      } 

      // ... 
     } 
    }); 
    */ 

    mAuth.fetchProvidersForEmail("[email protected]").addOnCompleteListener(this, new OnCompleteListener<ProviderQueryResult>() { 
     @Override 
     public void onComplete(@NonNull Task<ProviderQueryResult> task) { 
      Log.d(TAG, "signInWithCredential: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, "signInWithCredential", task.getException()); 
       Toast.makeText(SignInActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show(); 
      } else { 
       startActivity(new Intent(SignInActivity.this, MainActivity.class)); 
       finish(); 
      } 
     } 
    }); 
} 

}

답변

2
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken()); 
     mFirebaseAuth.signInWithCredential(credential) 
       .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { 
        @Override 
        public void onComplete(@NonNull Task<AuthResult> task) { 
         Log.d(TAG, "signInWithCredential: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, "signInWithCredential", task.getException()); 
          Toast.makeText(SignInActivity.this, "Authentication failed.", 
            Toast.LENGTH_SHORT).show(); 

          //((FirebaseAuthException)task.getException()).getErrorCode(); 

         } 

        } 

       }).addOnFailureListener(new OnFailureListener() { 
        @Override 
        public void onFailure(@NonNull Exception e) { 
         if(e instanceof FirebaseAuthUserCollisionException) 
         { 
          //Handle Auth Error Here 
          Toast.makeText(SignInActivity.this, e.toString(), 
            Toast.LENGTH_SHORT).show(); 

         }else if(e instanceof FirebaseAuthInvalidUserException) 
         { 
          //Handle Auth Error Here 
          Toast.makeText(SignInActivity.this, e.toString(), 
            Toast.LENGTH_SHORT).show(); 

         } 
        } 
     }); 

참고 : 우리가 유형 검사를 사용하는 것보다 더 나은 다음 해당 인증 예외에 대한 오류 코드를 얻을 수있는 경우 (instanceof를)

관련 문제