Development issue/problem:
From what I understand from the Firebase documents, a user who authenticates with an account should in principle log in with the same account if he is not already connected to another account.
In other words: If I create an account with a Google login and then (after logging out) try to login with a Facebook account, with the same email as for the Google account, I should see this exception in logcat :
And yes, I understand that this exception is not surprising. However, if I create an account on Facebook and then try to log in with a Google account, the provider of that account (Facebook) is changed to Google. The authentication did not fail this time, but it is not the expected result. I want to link each user to a specific account. How can I solve this problem? You can see the code below:
The SignInActivity public class extends AppCompatActivity by implementing GoogleApiClient.OnConnectionFailedListener,
View.OnClickListener {.
private static end string TAG = SignInActivity;
private static end string int RC_SIGN_IN = 9001 ;
closed GoogleApiClient mGoogleApiClient;
closed FirebaseAuth mFirebaseAuth;
closed FirebaseAuth.AuthStateListener mFirebaseAuthListener ;
Personal mCallbackManager ;
Override
protected by blank onCreate (StoredInstanceState Bundle) {
super.onCreate(storedInstanceState) ;
setContentView(R.layout.activity_sign_in) ;
// Facebook Login
FacebookSdk.sdkInitialize(getApplicationContext());
mCallbackManager = CallbackManager.Factory.create() ;
LoginButton mFacebookSignInButton = (LoginButton) findViewById(R.id.facebook_login_button) ;
mFacebookSignInButton.setReadPermissions(email, public_profile) ;
mFacebookSignInButton.registerCallback(mCallbackManager, new FacebookCallback() {
@Override
public null and void onSucces(LoginResult loginResult)) {
Log.d(TAG, facebook:onSucces: + loginResult);
firebaseAuthWithFacebook(loginResult.getAccessToken());
}
@Review
public null and void onCancel() {
Log.d(TAG, facebook:onCancel);
}
@Override
public void onError (FacebookException error) {
Log.d(TAG, facebook:onError, error);
}
})
// Google Login
// Fields
SignInButton mGoogleSignInButton = (SignInButton) findViewById(R.id.google_sign_in_button) ;
// set click listener
mGoogleSignInButton.setOnClickListener(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 /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build()
// Initialization of FirebaseAuth
mFirebaseAuth = FirebaseAuth.getInstance() ;
mFirebaseAuthListener = new FirebaseAuth.AuthStateListener() {
@General name
public null onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth)) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is logged in
Log.d(TAG, onAuthStateChanged:signed_in: + user.getUid()));
} otherwise {
// User is logged in
Log.d(TAG, onAuthStateChanged:signed_out);
}
}
};
}.
@Override
public void onStart() {
super.onStart();
mFirebaseAuth.addAuthStateListener(mFirebaseAuthListener);
}
@Overridepublic void onStop() {super.onStop();if (mFirebaseAuthListener != null) {mFirebaseAuth.removeAuthStateListener(mFirebaseAuthListener);}
private void firebaseAuthMetGoogle(GoogleSignInAccount acct) {
Log.d(TAG, firebaseAuthMetGooogle: + acct.getId());
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mFirebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener() {
@Override
public void onComplete(@NonNull task) {
Log.d(TAG, signInWithCredential:onComplete: + task.isSuccessful()) ;
// If the connection fails, display a message to the user. Upon successful login to// the authentication status of the listener is reported, and the processing logic of// the subscribed user can be processed in the listener. as (!task.isSuccessful()) {Log.w(TAG, signInCredential, task.getException());Toast.makeText(SignInActivity.this, authentication failed…,Toast.LENGTH_SHORT).show();} else {startActivity(new Intent(SignInActivity.this, MainActivity.class));finish();}}}}.
private void firebaseAuthWithFacebook(access token) {
Log.d(TAG, handleFacebookAccessToken: + token) ;
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
mFirebaseAuth.signInCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener() {
@Override
public null onComplete(@NonNull task) {
Log.d(TAG, signInCredential:onComplete: + task.isSuccessful() ;
// If the connection fails, display a message to the user. Upon successful login to// the authentication status of the listener is reported, and the processing logic of// the subscribed user can be processed in the listener. as (!task.isSuccessful()) {Log.w(TAG, signInWithCredential, task.getException());Toast.makeText(SignInActivity.this, Authentication failed.,Toast.LENGTH_SHORT).show();}.
otherwise {
startActivity (SignInActivity.this, MainActivity.class));
finish();
}
}
});
}.
/*
private void handleFirebaseAuthResult(AuthResult authResult) {
if (authResult != null) {
// Welcome user
FirebaseUser user = authResult.getUser() ;
Toast.makeText(this, Welcome + user.getEmail(), Toast.LENGTH_SHORT).show() ;
// Return to main activity
startActivity (new intention (this, MainActivity.class));
}
}
*/
@Check public blank
onClisk(View v) {
switch (v.getId()) {
register R.id.google_sign_in_button:
signIn();
break;
default:
return;
}
}.
private void signIn() {
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
Override
public void onActivityResult(int requestCode, int resultCode, intent data) {
super.onActivityResult(requestCode, resultCode, data) ;
mCallbackManager.onActivityResult (requestCode, resultCode, data) ;
// Result returned by running Intent from GoogleSignInApi.getSignInIntent(…);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSucces()) {
// Google Sign In successful, authenticate to Firebase
GoogleSignInAccount account = result.getSignInAccount();
firebaseAuthMetGoogle(account);
} otherwise {
// Google Sign In failed
Log.e(TAG, Google Sign In failed.);
}
}
}
@Define
public null onConnectionFailed (@NonNull ConnectionResult connectionResult) {
// An irreparable error has occurred and the Google API (including the connection) is not available
//.
Log.d(TAG, onConnectionFailed: + connection result);
Toast.makeText(this, Google Play Services error, Toast.LENGTH_SHORT).show();
}
}.
How can I solve this problem?
Solution 1:
See topic: https://groups.google.com/forum/#! searchin/ firebase-talk/liu/ firebase-talk/ms_NVQem_Cw/8g7BFk1IAAAAJ
This explains why this happens. This is due to a number of security issues where Google’s emails are monitored and Facebook’s emails are not.
Solution 2:
Go to Authentication > Login to suppliers, click Multiple accounts per email address, and select Allow multiple accounts with the same email address.
Solution 3:
I’m finally done with that logic:
If a user tries to log in to Facebook, but a user with the specified email address already exists (with a Google provider), this error occurs:
There is already an account with the same email address, but with different
accounts. Contact the supplier associated with this email address
.
So all you have to do is ask the user to login to Google (and then silently connect to Facebook with their existing account).
Solution 4:
To minimize the number of login clicks without compromising account security, Firebase Authentication has a Trusted Provider concept where the Identity Provider is also the email service provider. For example, Google is a trusted provider for @gmail.com addresses, Yahoo is a trusted provider for @yahoo.com addresses, and Microsoft is a trusted provider for @outlook.com addresses.
In One account per email address mode, Firebase will attempt to bind the account based on the email address. When a user registers with a trusted provider, he is immediately logged into his account because we know he has the email address.
If there is an existing account with the same email address, but it was created with unreliable data (e.g. an unreliable supplier or an unreliable password), the previous data will be deleted for security reasons. A phisher (who does not own the email address) can create a first account – deleting the first account prevents the phisher from later accessing that account.
Jin Liu.
Solution No 5:
In Firebase, it is very important to check the user’s inbox when they first connect to Facebook by sending them a confirmation email.
After checking the email you can login to Facebook and Gmail if the user uses @gmail.com as email address.
Log in to Facebook -> Click on the check link in the email -> Log in to Gmail -> Log in to Facebook (OK)
Log in to Facebook -> Log in to Gmail -> Click on the link in Check Email -> Log in to Facebook (NOT OK)
If you have not checked the Facebook email before the user logs out and tries to log in with his or her Gmail, you will not be able to log in to Facebook once he or she has logged in with his or her Gmail.
Solution No 6:
I had the same problem. So I deleted the Google account and the Facebook account at
firebase console > authentication > user
that you connected to before testing another device.
Solution No 7:
The ability to create multiple accounts with the same email address is what you are looking for.
This only works if you check the emails in your backend and it is a link for your users. If you are using a Firebase Id, no user will be saved.
Solution No 8:
I had the same problem, just go to the firebase console and then, in the authentication category, delete the user you want.
Works for me.
Good luck!
Related Tags:
firebase facebook logout,firebase facebook login nodejs,login using facebook credentials,facebook login using javascript,firebase android google signin,login with facebook in node js,google sign-in method,auth provider firebase,how to link providers firebase,firebase merge anonymous,linkandretrievedatawithcredential,facebookauthprovider getcredential flutter,firebase user roles,firebase auth custom claims,firebase web setup,firebase admin create user,role based authorization in angular,firebase organizations,social login using firebase in android,firebase facebook login android example,firebase twitter login android,firebase google login android,facebook login in android,twitter login integration in android example,firebase "auth/account-exists-with-different-credential,firebase authentication in facebook using javascript,firebase authentication facebook web,firebase console,flutter facebook login firebase,google facebook authentication,android login with facebook and google