firebaseui-web icon indicating copy to clipboard operation
firebaseui-web copied to clipboard

Link Multiple Accounts doesn't work! auth/account-exists-with-different-credential

Open AntonioVentilii opened this issue 2 years ago • 42 comments

If the user first login using google, and then using any other provider (for example github) the result is below... (it can be tested in the demo, same results)

Screenshot 2023-08-04 at 17 08 40

AntonioVentilii avatar Aug 04 '23 15:08 AntonioVentilii

I have been experiencing a related issue with Google and Github providers. When I first login with Github all goes well. When I later login with Google, same email, I get logged in but the two providers are not linked. The Github authentication is replaced with just google in the Firebase console. When I later try to login with Github I am unable but no error is displayed. I have tested with the demo app and I have been able to reproduce the error.

0xbrayo avatar Aug 09 '23 21:08 0xbrayo

التقاط

Hello Antonio you should go to authentication and then Settings and select create multiple accounts for each identity provider

mahmoudaboalwafa1 avatar Aug 10 '23 08:08 mahmoudaboalwafa1

التقاط

Hello Antonio you should go to authentication and then Settings and select create multiple accounts for each identity provider

That doesn't fix the issue, he wants as I do too, to link multiple auth providers to a single account.

0xbrayo avatar Aug 10 '23 12:08 0xbrayo

@brayo-pip Hello brayo I have been facing this problem and I have selected the option that is in the image and I succeeded I think it is preferable to delete all users and make an update to the cookies

mahmoudaboalwafa1 avatar Aug 11 '23 09:08 mahmoudaboalwafa1

That will make two accounts for each Provider. If I have email [email protected] and I sign with Google, I'll have a google entry in firebase console. When I sign in with Github using [email protected] that will create a separate entry in the firebase console. But we want to have a single entry with both providers linked. I don't have a screenshot to link right now but I hope you are familiar with what I hope to achieve. The linked entry should show both icons of the linked providers, Google and Github.

0xbrayo avatar Aug 11 '23 19:08 0xbrayo

I understand you now, you want when a user registers with a Google account, and we assume that there is another button on a site when logging in, and this button registers with a GitHub account, meaning two accounts are added and not a change between a Google account and a GitHub, right

mahmoudaboalwafa1 avatar Aug 12 '23 06:08 mahmoudaboalwafa1

@brayo-pip Hello brayo I have been facing this problem and I have selected the option that is in the image and I succeeded I think it is preferable to delete all users and make an update to the cookies

But this way the faceboook email is missing in the token after login.

damencho avatar Aug 23 '23 18:08 damencho

The problem is that in case of an error like auth/account-exists-with-different-credential the signInFailure callback is not executed. The case when using a popup the problem is more visible as the popup closes without any notification and you are left with an empty page.

damencho avatar Aug 23 '23 19:08 damencho

Is there a fix for this? Ideally the signIfFailure would be called and worst case our callback can try to merge accounts. I would expect this UI to handle this use case by default but since it doesnt what is the recommended fix for this?

dbrody avatar Dec 29 '23 05:12 dbrody

Any update on this?

It seems to me that the Link accounts that use the same email is a bit useless as not working as one's would expect and not preventing auth/account-exists-with-different-credential, for instance:

      try {
        const userCredential = await signInWithPopup(auth, provider);

        console.log("userCredential", userCredential);
        const { isNewUser } = getAdditionalUserInfo(userCredential);
        console.log("isNewUser", isNewUser);

        if (isNewUser) {
          await auth.currentUser.delete();
          throw new Error(`${email} is not registered.`);
        } else navigate(`/${auth.currentUser.tenantId}/projects`);
      } catch (error) {
        if (error.code === "auth/account-exists-with-different-credential") {
          const test = OAuthProvider.credentialFromError(error);
          console.log("test", test);
        } else throw error;
      }
    };

I have multiple providers, Google and Microsoft for instance and I would expect this code to work seamlessly regardless of the selected provider.

aress31 avatar Dec 30 '23 14:12 aress31

Same issue here, on version 6.1.0. It can result on user being stuck on a white page. The UI container is present in the DOM, but no content, no loading, nothing.

dimitriz09 avatar Apr 11 '24 17:04 dimitriz09

Im having this same problem while trying to login with Google and Facebook with the same email. At first login with Facebook works, but one I log with Google, then Facebook login returns firebase_auth/account-exists-with-different-credential

pamafe1976 avatar Apr 12 '24 02:04 pamafe1976

I am facing the same issue - I can link accounts when user first logs in with gmail and then Github. However, when the user first logs in with Github and then with Gmail the "account-exists-with-different-credential" doesn't get thrown thus the linking doesn't happen and the Github account gets overwritten with Gmail. Afterwards if the user tries to log in with Github they are prompted to link the accounts and both accounts are finally linked.

ms-aija avatar May 02 '24 10:05 ms-aija

I'm also facing this issue.

kbrennan7272 avatar May 24 '24 13:05 kbrennan7272

I am also noticing this happening when there are no providers linked at all when trying to login with microsoft for the first time.

kdawgwilk avatar May 26 '24 06:05 kdawgwilk

works on google, but not on msft - when initial account is mail/pass

FinestMaximus avatar May 29 '24 04:05 FinestMaximus

I reached out to firebase support and they told me this is specific to Microsoft 365 business accounts? Why would the providers account type have any result on this auth error?

kdawgwilk avatar May 31 '24 07:05 kdawgwilk

I can confirm this. Also, the signInSuccessWithAuthResult() callback is not called.

I have also tried to upgrade Firebase Auth to the version that uses Google Cloud Identity Platform, but with no success. (I assumed that it might be a "newer" version than the so-called "legacy", i.e. Firebase Auth alone).

Neither of the two executes the signInSuccessWithAuthResult() callback and get stuck at a white screen, as described above.

Is it a Firebase/Identity Platform bug then?

roberthangu avatar Jun 15 '24 10:06 roberthangu

Found this in the docs and working on implementation to see if it fixes the issue. It's really odd that we have to link the provider to another one despite the setting to merge the accounts with the same email turned on https://firebase.google.com/docs/auth/web/microsoft-oauth#expandable-1

kdawgwilk avatar Jun 16 '24 07:06 kdawgwilk

Having to manually link accounts by saving and loading credentials and asking the user to sign in via some identity provider they have used in the past (out of many) is not good design/UX. The "link accounts with same email" does not work the way it implies to.

neil-119 avatar Jul 07 '24 16:07 neil-119

is there any workaround to sign in the first time with Microsoft 365?

asoseil avatar Jul 09 '24 12:07 asoseil

got same issue here. when using google and facebook.

Panigale avatar Aug 13 '24 08:08 Panigale

Have the same issue, when using a custom token implementation to sign in first, then signing in with a Microsoft account with the same email, I get this error

jacobshirley avatar Aug 16 '24 16:08 jacobshirley

Same issue here, looking for a solution.

akroll1 avatar Aug 16 '24 21:08 akroll1

Same issue here,

First approch

I've tried the code pointed by @kdawgwilk with no success

Found this in the docs and working on implementation to see if it fixes the issue. It's really odd that we have to link the provider to another one despite the setting to merge the accounts with the same email turned on firebase.google.com/docs/auth/web/microsoft-oauth#expandable-1

There is no "credential" field in the error (step 2) but a customData with a lot of information : federatedId or id in the rawUserInfo marked as KEY below is the key of the Microsoft account. I can link this id with a backend function in a second step and launch again the signIn.

customData: {
	appName: "[DEFAULT]"
	email: XXX,
	_tokenResponse: {
		context: ""
		displayName: XXX
		email: XXX
		emailVerified: false
		federatedId: "http://microsoft.com/KEY"
		fullName:  XXX
		kind: "identitytoolkit#VerifyAssertionResponse",
		localId: Firebase UID
		needConfirmation: true
		oauthAccessToken: XXX
		oauthExpireIn: 3743
		oauthIdToken: XXX
		pendingToken: XXX
		providerId: "microsoft.com"
		rawUserInfo:  "{\"businessPhones\" :[],\"preferredLanguage\":null,\"mail\":null,\"mobilePhone\":null,\"officeLocation\":null,\"displayName\":\"XXX\",\"surname\":null,\"givenName\":null,\"jobTitle\":null,\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users/$entity\",\"id\":\"KEY\",\"userPrincipalName\":\"XXX\"}"
		verifiedProvider: Array(1)
			0: "microsoft.com"

BTW it's not a proper solution for a production usage just a temporary workaround. Do you have a better workaround ? It seems very fragile...

Second approch and solution I used

Presentation of my own case:

  1. an administrator register the user (I store a token and the associated email in my rtdb)
  2. the user follow a link with the token and signup with the provider
export async function signUpWithMicrosoftProvider(
    temporaryId: SignInEmailAndPasswordProps,
) {
    const provider = new OAuthProvider("microsoft.com");
    const result = await signInEmailAndPassword(temporaryId);
    await linkWithPopup(result.user, provider);
    await unlink(result.user, "password");
    return result;
}

In the callback function of my Microsoft button, I call a backend function (which checks the token and creates the new account with the user's e-mail address in the rtdb and a temporarily generated password). The password is returned and passed as a parameter along with the email to log the user in before linking the Microsoft account and removing the password provider.

I'll add error handling and reinforcement of the password validity period to avoid security problems.

FabriceBazzaro avatar Aug 20 '24 16:08 FabriceBazzaro