6

Sto usando la documentazione di Firebase per utilizzare Facebook login la mia applicazione Android. Sono in grado di accedere con successo agli utenti tramite Google e Twitter. Ma quando clicco su Accedi con Facebook, il pulsante sta cambiando al pulsante di disconnessione. In realtà dovrebbe reindirizzare l'attività di accesso, perché ho configurato FirebaseAuth.AuthStateListener.FirebaseAuthUserCollisionException?

Sto postando il Activity qui, per favore fatemi sapere se sto facendo qualcosa di sbagliato.

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

Finalmente ho capito il motivo per cui Facebook login non funziona. Questo perché ho già effettuato l'accesso all'app utilizzando Google Signin. Poiché la mia e-mail per Google e Facebook è la stessa, sta dando FirebaseAuthUserCollisionException. Avrei dovuto eseguire il debug dell'applicazione prima di pubblicare la domanda in Stackoverflow.

Update2

non sto chiudendo questa domanda in quanto può aiutare qualcuno che ha affrontato la situazione come me. E aggiornerò anche la soluzione per FirebaseAuthUserCollisionException, come ho scavato di più in esso.

+0

Come hai fatto a gestire l'errore di collisione? Sei in grado di unire entrambi i fornitori in un unico account Firebase? –

risposta

8

Ho affrontato lo stesso problema ed è così che sono andato in giro.
Se l'attività non ha esito positivo, sto verificando se l'eccezione generata è instanceof FirebaseAuthUserCollisionException. Se sì, viene visualizzato un brindisi all'utente che dice "L'account con e-mail esiste già!".

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(); 
        } 
       } 
      }); 
} 

credito: Check if given email exists

+0

Comunque una buona soluzione. Complimenti! – sud007