My app uses Firebase authentication with 2 providers: Facebook and Google. To allow users to create both Facebook and Google accounts with the same email, I went to Firebase console and checked an option to allow multiple acoounts for email address.
Now it works, but for Facebook, email is always null. How can I get top level email address (linked to multiple accounts) in case when user decides to login with Facebook. I don't want to link providers into one account, I want to keep "allow multiple accounts for one mail address" turned on.
Any ideas how to get mail address in this case?
[edit]
Initialization for Google and Facebook apis:
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();
mAuthListener = firebaseAuth ->
{
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null)
{
// User is signed in
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
String uuid = user.getUid();
String mail = user.getEmail();
currentUserUid = user.getUid();
//Toast.makeText(LoginActivity.this, "Zalogowano. Email: " + user.getEmail() + " uid: " + user.getUid(),
// Toast.LENGTH_SHORT).show();
if (!logout)
{
List<? extends UserInfo> provider = user.getProviderData();
AuthSocial(user, currentLoginType); //if "allow multiple accounts for mail enabled, user.getEmail always returns null for Facebook, how to get correct top level email for "multi account" here?
}
else
{
//mAuth.signOut();
}
}
else
{
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
}
};
// [START initialize_fblogin]
// Initialize Facebook Login button
mCallbackManager = CallbackManager.Factory.create();
LoginButton loginButton = (LoginButton) findViewById(R.id.bt_go_facebook);
loginButton.setReadPermissions("email", "public_profile");
loginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>()
{
@Override
public void onSuccess(LoginResult loginResult)
{
Log.d(TAG, "facebook:onSuccess:" + loginResult);
handleFacebookAccessToken(loginResult.getAccessToken());
currentLoginType = "facebook";
}
@Override
public void onCancel()
{
Log.d(TAG, "facebook:onCancel");
// [START_EXCLUDE]
//updateUI(null);
// [END_EXCLUDE]
}
@Override
public void onError(FacebookException error)
{
Log.d(TAG, "facebook:onError", error);
// [START_EXCLUDE]
//updateUI(null);
// [END_EXCLUDE]
}
});
// [END initialize_fblogin]
Because facebook allow users to sign-in only with a phone number there are cases in which users do not update their accounts with their email address. Unfortunately, in those cases you cannot have their emaill addresses at all. To solve this, you can use in stead of email address, the provided phone number or the unique Google/Facebook id
.
In order to get the email address from facebook profie, you need to use registerCallback
method on the callbackManager
object. Here is the code:
CallbackManager callbackManager = CallbackManager.Factory.create();
facebookLoginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
AccessToken accessToken = loginResult.getAccessToken();
handleFacebookAccessToken(accessToken);
GraphRequest request = GraphRequest.newMeRequest(accessToken, new GraphRequest.GraphJSONObjectCallback() {
@Override
public void onCompleted(JSONObject jsonObject, GraphResponse graphResponse) {
if(jsonObject != null){
Profile profile = Profile.getCurrentProfile();
String userEmail = jsonObject.optString("email"); // Facebook userEmail
}
}
});
Bundle bundle = new Bundle();
bundle.putString("fields", "email");
request.setParameters(bundle);
request.executeAsync();
}
@Override
public void onCancel() {}
@Override
public void onError(FacebookException exception) {}
});
And this the way in which you can check wherever your user loged-in with Google
or Facebook
.
if (firebaseUser != null) {
for (UserInfo userInfo : firebaseUser.getProviderData()) {
if (userInfo.getProviderId().equals("facebook.com")) {
Toast.makeText(MainActivity.this, "User is signed in with Facebook", Toast.LENGTH_SHORT).show();
}
if (userInfo.getProviderId().equals("google.com")) {
createShoppingList(userModel, listName);
Toast.makeText(MainActivity.this, "You are signed in Google!", Toast.LENGTH_SHORT).show();
}
}
}