14

Ho implementato correttamente il codice di esercitazione da https://firebase.google.com/docs/auth/android/facebook-login per l'integrazione degli accessi di autenticazione Firebase con Facebook. Gli utenti creati con successo nella console di autenticazione di Firebase.Campo di posta elettronica vuoto dell'utente Firebase Utente che utilizza Facebook Login Integration (Firebase 3.0)

Tuttavia, ho notato che il campo Email nell'oggetto utente è vuoto (-). Stranamente, ho recuperato le informazioni e-mail direttamente dagli oggetti risultato del provider usando GraphRequest usando il token acquisito.

In base alla documentazione che ho letto (https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseUser.html#getEmail()), il campo di posta elettronica deve essere compilato dai provider di accesso.

Alcuni comportamenti strani supplementari:

  1. Dopo l'accesso, l'onAuthStateChanged viene chiamato due volte. Il valore di firebaseAuth.getCurrentUser(). GetProviderId() è Firebase in entrambe le occasioni
  2. Si tenta di elencare i provider dall'oggetto FirebaseUser, user.getProviderData(). Ho ottenuto due provider: firebase e facebook.com
  3. Quando ho provato ad aggiornare l'e-mail utilizzando FirebaseUser.updateEmail (event.getEmail()), ho ricevuto questo errore: si è verificato un errore interno. [EMAIL_EXISTS]

C'è qualcosa che mi manca o ho fatto qualcosa di sbagliato?

Ecco il mio codice:

public class LoginActivity extends AppCompatActivity { 
    private static final String TAG = "LOGIN_ACTIVITY"; 
    private static final int RC_SIGN_IN = 777; 
    private EventBus eventBus; 
    private SweetAlertDialog pDialog; 

    private FirebaseAuth mAuth; 
    private FirebaseAuth.AuthStateListener mAuthListener; 
    private CallbackManager mCallbackManager; 
    private ImageView mPasswordVisibilityView; 
    private TextView txtPassword; 
    private boolean justEnteredAuthStateChanged = false; 
    private GoogleApiClient mGoogleApiClient; 


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

     setContentView(R.layout.login); 

     // Firebase 
     mAuth = FirebaseAuth.getInstance(); 

     mAuthListener = new FirebaseAuth.AuthStateListener() { 
      @Override 
      public void onAuthStateChanged(@NonNull final FirebaseAuth firebaseAuth) { 
       final FirebaseUser user = firebaseAuth.getCurrentUser(); 
       if (user != null) { 
        // User is signed in 
        Util.logassert("Auth Provider = " + firebaseAuth.getCurrentUser().getProviderId()); // this is called twice, values of Provider = Firebase 
        Util.logassert("total provider = " + user.getProviderData().size()); // output = 2. "Firebase" and "facebook.com" 
        for (int i = 0; i < user.getProviderData().size(); i++) { 
         UserInfo info = user.getProviderData().get(i); 
         Util.logassert(info.getProviderId() + ", email = " + info.getEmail()); // both empty 
         Util.logassert("current provider = " + info.getProviderId() + " - " + info); 
        } 

       } else { 
        Util.logassert("onAuthStateChanged user logged out"); 
       } 
       // ... 

      } 
     }; 
     mAuth.addAuthStateListener(mAuthListener); 

     // Firebase Facebook TapAuth 
     // Initialize Facebook Login button 

     mCallbackManager = CallbackManager.Factory.create(); 

     LoginManager.getInstance().registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() { 
      @Override 
      public void onSuccess(LoginResult loginResult) { 
       Util.logassert("facebook:onSuccess:" + loginResult); 
       handleFacebookAccessToken(loginResult.getAccessToken()); 
       Util.logassert("granted = " + loginResult.getRecentlyGrantedPermissions()); // output [email and public_profile] 
       Util.logassert("denied = " + loginResult.getRecentlyDeniedPermissions()); 
      } 

      @Override 
      public void onCancel() { 
       Util.logassert("facebook:onCancel"); 
       // ... 
      } 

      @Override 
      public void onError(FacebookException error) { 
       Util.logassert("facebook:onError" + error.getMessage()); 
       // ... 
      } 
     }); 

     FancyButton btnFacebook = (FancyButton) findViewById(R.id.btn_facebook_share); 
     btnFacebook.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       LoginManager.getInstance().logInWithReadPermissions(LoginActivity.this, Arrays.asList("public_profile", "email")); 
       Util.logassert("try facebook login"); 
      } 
     }); 



     txtPassword = (EditText) findViewById(R.id.input_password); 
    } 



    private void handleFacebookAccessToken(AccessToken token) { 
     Util.logassert("handleFacebookAccessToken:" + token); 

     GraphRequest request = GraphRequest.newMeRequest(
       token, 
       new GraphRequest.GraphJSONObjectCallback() { 
        @Override 
        public void onCompleted(
          JSONObject object, 
          GraphResponse response) { 
         // Application code 
         Log.v("LoginActivity", response.toString()); 
         Util.logassert("graph res = " + response.getRawResponse()); 

         try { 
          /* successfully output email address from graph request here */ 
          FbGraphEvent event = new FbGraphEvent(response.getJSONObject().getString("email"), response.getJSONObject().getString("name")); 
          EventBus.getDefault().postSticky(event); 
         } catch (Exception e) { 
          Log.e("MomInvoice", "Error in parsing json fb graph", e); 
         } 
        } 
       }); 
     Bundle parameters = new Bundle(); 
     parameters.putString("fields", "email,name"); 
     request.setParameters(parameters); 
     request.executeAsync(); 

     AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken()); 

     mAuth.signInWithCredential(credential) 
       .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { 
        @Override 
        public void onComplete(@NonNull Task<AuthResult> task) { 
         Util.logassert("signInWithCredential:onComplete:" + task.isSuccessful()); 


         if (!task.isSuccessful()) { 
          Util.logassert("signInWithCredential failed coz = " + task.getException().getMessage()); 
          Toast.makeText(LoginActivity.this, "Authentication failed :(", 
            Toast.LENGTH_SHORT).show(); 
         } 

        } 
       }); 
    } 


    @Override 
    public void onStart() { 
     super.onStart(); 
     Util.logassert("masuk onStart LoginActivity"); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
    } 

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

    @Override 
    protected void onNewIntent(Intent intent) { 
     super.onNewIntent(intent); 
    } 

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

     super.onActivityResult(requestCode, resultCode, data); 

     if (mCallbackManager != null) { 
      mCallbackManager.onActivityResult(requestCode, resultCode, data); 
      Util.logassert("hasilx " + requestCode + " = " + resultCode); 
     } 

    } 
} 
+0

Ho lo stesso problema, email vuota dal login di Facebook. Login Google Proverò presto –

+0

Non mi è familiare l'SDK Android, ma mi trovavo di fronte a un problema simile nel javascript sdk w/login di google. A quanto ho capito, Firebase 3.0 non include più i dettagli dell'utente nella risposta iniziale a una chiamata di autenticazione. questo potrebbe essere il motivo per cui la tua chiamata successiva sta restituendo la posta elettronica. hth. http://stackoverflow.com/questions/37618332/firebase-3-additional-auth-scope-data – Brandon

+0

@Muhammad Rayhan, hai mai risolto questo problema? Sto avendo gli stessi problemi. L'email non è contenuta da nessuna parte. Lo stesso per Twitter, ma il login di Twitter in origine richiede un ulteriore passaggio per ottenere e-mail. – efemoney

risposta

19

dopo aver letto post in firebase-talk gruppo google qui https://groups.google.com/forum/#!topic/firebase-talk/gPGNq-IkTLo, ho trovato la risposta. Il problema è accaduto perché sto utilizzando "Consenti la creazione di più account con lo stesso indirizzo email" nel metodo di accesso Auth Firebase.

Così ho cambiato l'opzione in: "Prevenire la creazione di più account con lo stesso indirizzo email" può funzionare correttamente ora. È semplice. È vero, ho bisogno di più logica per unire gli account con lo stesso indirizzo email, ma va bene.

Forse chiunque altro ha lo stesso problema, può anche provare questo, e si spera che sia risolto pure.

+2

Grazie per questo. Ho lottato con questo per sempre. – Seiyria

+0

Ragazzi ho sofferto a lungo con questo. Grazie,! 3 (Mi piace) – Ishaan

0

@Muhammad Rayhan. Anch'io ho fatto lo stesso. Ho usato FirebaseUser.updateEmail() dopo aver ricevuto l'email da Fb GraphRequest. Ha funzionato senza problemi.

+0

Ciao @efeturi, sfortunatamente non funziona per me. Ho ricevuto questo errore quando chiamavo FirebaseUser.updateEmail(): errore: si è verificato un errore interno. [EMAIL_EXISTS] –

+0

Innanzitutto, non intendevo aggiungere una risposta. Sono sull'app per Android Stack Exchange e intendevo aggiungere un commento. Detto questo, hai controllato che l'email con cui stai aggiornando non sia già tra i tuoi utenti? Ho avuto un caso con Twitter dopo questo in cui updateEmail non funzionava per un utente di Twitter. Ho scoperto che ho usato la stessa email per il mio Facebook e Twitter. – efemoney

+0

Nel mio caso, ho scoperto che alcuni utenti di Facebook si sono registrati con il proprio numero di telefono e il campo di posta elettronica è vuoto in modo permanente e non importa quello che fai, non riceverai un'email. @efemoney – Po10cio

0

Ho avuto lo stesso problema. È stato causato dalla creazione dell'accesso a Facebook senza autorizzazioni di lettura, testato l'accesso, tutto OK - quindi aggiunto le autorizzazioni di lettura per la posta elettronica.

Facebook ha mostrato la finestra delle autorizzazioni aggiornate, ma Firebase non ha preso la nuova email.

Ho dovuto eliminare l'utente nella console Firebase. Ha eseguito di nuovo l'app, effettuato l'accesso e l'e-mail ora mostra.

6

Ho riscontrato lo stesso problema, in cui l'e-mail era impostata su "-" sull'autenticazione firebase. Mi mancava il permesso di leggere l'e-mail, che ho risolto con:

LoginButton mFacebookSignInButton = (LoginButton) findViewById(R.id.facebook_sign_in_button); 
mFacebookSignInButton.setReadPermissions("email", "public_profile"); 

Spero che questo aiuti qualcuno in futuro ad avere lo stesso problema.

+0

Ho lo stesso problema, nonostante l'aggiunta di permessi di lettura per "email" – SagunKho

1

Ho trovato la soluzione. Ecco il mio codice

import android.app.ProgressDialog; 
import android.content.Intent; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.ImageButton; 

import com.app.pizzawheel.Common.Globals; 
import com.facebook.AccessToken; 
import com.facebook.AccessTokenTracker; 
import com.facebook.CallbackManager; 
import com.facebook.FacebookCallback; 
import com.facebook.FacebookException; 
import com.facebook.FacebookSdk; 
import com.facebook.GraphRequest; 
import com.facebook.GraphResponse; 
import com.facebook.login.LoginManager; 
import com.facebook.login.LoginResult; 
import com.facebook.login.widget.LoginButton; 
import com.google.android.gms.tasks.OnCompleteListener; 
import com.google.android.gms.tasks.Task; 
import com.google.firebase.auth.AuthCredential; 
import com.google.firebase.auth.AuthResult; 
import com.google.firebase.auth.FacebookAuthProvider; 
import com.google.firebase.auth.FirebaseAuth; 
import com.google.firebase.auth.FirebaseUser; 
import android.support.annotation.NonNull; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.util.Arrays; 

public class GetStartedActivity extends AppCompatActivity { 

    CallbackManager callbackManager; 
    AccessTokenTracker accessTokenTracker; 
    AccessToken accessToken; 
    private FirebaseAuth mAuth; 
    ProgressDialog progress; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     FacebookSdk.sdkInitialize(this.getApplicationContext()); 

     setContentView(R.layout.activity_getstarted); 
     getSupportActionBar().hide(); 
     mAuth = FirebaseAuth.getInstance(); 

     callbackManager = CallbackManager.Factory.create(); 
     final LoginButton loginButton = (LoginButton) findViewById(R.id.fb_login); 
     final ImageButton btnFBLogin = (ImageButton)findViewById(R.id.btn_fb_login); 
     loginButton.setReadPermissions("email", "public_profile"); 

     if (loginButton != null) { 
      loginButton.registerCallback(callbackManager, 
        new FacebookCallback<LoginResult>() { 
         @Override 
         public void onSuccess(LoginResult loginResult) { 
          // App code 
          loginButton.setVisibility(View.INVISIBLE); 
          btnFBLogin.setVisibility(View.VISIBLE); 
          accessToken = loginResult.getAccessToken(); 
          FBLogin(); 

         } 

         @Override 
         public void onCancel() { 
          // App code 
         } 

         @Override 
         public void onError(FacebookException exception) { 
          // App code 
         } 
      }); 
     } 
     if(AccessToken.getCurrentAccessToken()!=null) { 
      accessToken = AccessToken.getCurrentAccessToken(); 
      btnFBLogin.setVisibility(View.VISIBLE); 
     } 
     btnFBLogin.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       FBLogin(); 
      } 
     }); 

    } 

    private void FBLogin(){ 
     progress = new ProgressDialog(GetStartedActivity.this); 
     progress.setMessage("Please Wait..."); 
     progress.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
     progress.setCancelable(false); 
     progress.show(); 

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

         if (task.isSuccessful()) { 
          GraphRequest request = GraphRequest.newMeRequest(accessToken, new GraphRequest.GraphJSONObjectCallback(){ 

           @Override 
           public void onCompleted(JSONObject object, GraphResponse response) { 
            progress.hide(); 
            progress.dismiss(); 
            try { 
             Globals.email_address = object.getString("email"); 
             Globals.first_name = object.getString("first_name"); 
             Globals.last_name = object.getString("last_name"); 
            } catch (JSONException e) { 
             e.printStackTrace(); 
            } 

            Intent intent = new Intent(GetStartedActivity.this, WelcomeActivity.class); 
            startActivity(intent); 
            finish(); 
           } 
          }); 
          Bundle parameters = new Bundle(); 
          parameters.putString("fields","id,email,first_name,last_name"); 
          request.setParameters(parameters); 
          request.executeAsync(); 
          // Sign in success, update UI with the signed-in user's information 

         } else { 
          progress.hide(); 
          progress.dismiss(); 
          // If sign in fails, display a message to the user. 
//         Log.w(TAG, "signInWithCredential:failure", task.getException()); 
//         Toast.makeText(FacebookLoginActivity.this, "Authentication failed.", 
//           Toast.LENGTH_SHORT).show(); 
//         updateUI(null); 
         } 

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

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
    } 
} 
Problemi correlati