web-dev-qa-db-ger.com

Leeres E-Mail-Feld des Firebase-Auth-Benutzers über die Facebook-Login-Integration (Firebase 3.0)

Ich habe erfolgreich Tutorial-Code von https://firebase.google.com/docs/auth/Android/facebook-login bereitgestellt, um Firebase-Auth-Anmeldungen in Facebook zu integrieren. Die Benutzer wurden erfolgreich in der Firebase Auth-Konsole erstellt.

Ich habe jedoch festgestellt, dass das E-Mail-Feld im Benutzerobjekt leer ist (-). Seltsamerweise habe ich die E-Mail-Informationen mithilfe von GraphRequest und dem erworbenen Token direkt von Provider-Ergebnisobjekten abgerufen.

Basierend auf der Dokumentation, die ich gelesen habe ( https://firebase.google.com/docs/reference/Android/com/google/firebase/auth/FirebaseUser.html#getEmail () ), sollte das E-Mail-Feld ausgefüllt werden von Login-Anbietern.

Einige zusätzliche seltsame Verhaltensweisen:

  1. Nach erfolgreicher Anmeldung wird der onAuthStateChanged zweimal aufgerufen. Der Wert von firebaseAuth.getCurrentUser (). GetProviderId () ist in beiden Fällen Firebase .__
  2. Ich versuche, die Anbieter des FirebaseUser-Objekts user.getProviderData () aufzulisten. Ich habe zwei Anbieter: Firebase und Facebook.com
  3. Bei dem Versuch, die E-Mail mit FirebaseUser.updateEmail (event.getEmail ()) zu aktualisieren, wurde die folgende Fehlermeldung angezeigt: Ein interner Fehler ist aufgetreten. [ EMAIL EXISTIERT ]

Gibt es etwas, was ich vermisst habe oder habe ich etwas falsch gemacht?

Hier ist mein Code:

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

    }
}
17
Muhammad Rayhan

nachdem ich den Beitrag in der Google-Gruppe von firebase-talk hier gelesen hatte https://groups.google.com/forum/#!topic/firebase-talk/gPGNq-IkTLo , fand ich die Antwort heraus. Das Problem ist aufgetreten, weil ich in der Anmeldemethode von Firebase Auth die Option "Erstellung mehrerer Konten mit derselben E-Mail-Adresse zulassen" verwende.

Daher ändere ich die Option in: "Verhindern, dass mehrere Konten mit derselben E-Mail-Adresse erstellt werden", funktioniert sie jetzt ordnungsgemäß. So einfach ist das. Es stimmt, ich brauche mehr Logik, um Konten mit derselben E-Mail-Adresse zusammenzuführen, aber es ist in Ordnung.

Vielleicht kann jeder, der das gleiche Problem hat, es auch versuchen, und hoffentlich ist es auch gelöst.

33
Muhammad Rayhan

Ich habe das gleiche Problem gefunden, bei dem E-Mail in Firebase-Authentifizierung auf "-" gesetzt wurde. Mir fehlte die Erlaubnis zum Lesen von E-Mails, die ich korrigiert habe:

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

Ich hoffe, dass dies jemandem in Zukunft hilft, das gleiche Problem zu haben.

7

Einige Facebook-Konten werden mithilfe von Handynummern erstellt. Wenn wir also nach einer E-Mail-Adresse fragen, erhalten wir eine leere Zeichenfolge.

In der folgenden Abbildung können Sie sehen, dass der Facebook-Account entweder Primärer Kontakt als E-Mail-Adresse oder Handynummer festlegen kann. Wenn eine Person die Handynummer als primär markiert hat, kann ihre E-Mail-Adresse nicht abgerufen werden.

In meinem Fall hatte ich vergessen, meinen Facebook-Account zu verifizieren, sodass meine E-Mail-Adresse ursprünglich nicht einmal im primären Kontakt angezeigt wurde. Wenn Sie also keine E-Mail-Adresse erhalten, gehen Sie bitte zu den allgemeinen Einstellungen und prüfen Sie, ob für das primäre Konto eine E-Mail-Adresse festgelegt ist oder nicht.

enter image description here

3
Arshak

Ich habe die Lösung gefunden ... Hier ist mein Code

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

Ich habe diesen Weg gelöst

 _facebookLoginButton.setReadPermissions(Arrays.asList(
                "email", "public_profile"));
            _facebookLoginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
                @Override
                public void onSuccess(LoginResult loginResult) {
                    credential = FacebookAuthProvider.getCredential(facebookAccessToken.getToken());
                    GraphRequest request = GraphRequest.newMeRequest(
                        loginResult.getAccessToken(), (me, response) -> {

                            if (response.getError() != null) {
                                // handle error
                                hideProgress();
                                Logcum.w(" GirisActivity ", "facebookSignIn: Giriş anında hata oluştu", response.getError().getException());
                            } else {

                                user_email = response.getJSONObject().optString("email");
                                facebookSignInCredential(user_email);

                            }
                        });

                    Bundle parameters = new Bundle();
                    parameters.putString("fields", "email");
                    request.setParameters(parameters);
                    request.executeAsync();

                }

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

                }

                @Override
                public void onError(FacebookException error) {
                    Log.d(TAG, "facebook:onError", error);
                    hideProgress(); // progresi gizle
                }
            });
0
Erhan Biçer

@Muhammad Rayhan. Ich habe auch dasselbe gemacht. Ich habe FirebaseUser.updateEmail() verwendet, nachdem ich die E-Mail von Fb GraphRequest erhalten habe. Es hat ohne Probleme funktioniert.

0
efemoney

Ich hatte das gleiche Problem. Es wurde verursacht, indem das Facebook-Login ohne Leseberechtigung erstellt wurde, das Login getestet wurde, alles in Ordnung - und dann die Leseberechtigungen für E-Mail hinzugefügt.

Facebook zeigte das aktualisierte Berechtigungsdialogfeld an, Firebase hat jedoch die neue E-Mail nicht erfasst.

Ich musste den Benutzer in der Firebase-Konsole löschen. Die App erneut gestartet, eingeloggt und die E-Mail wird angezeigt.

0
ben_the_builder