This error occurs when a user tries to sign in with a provider (like Google) using an email already linked to another provider (like Facebook). Enable account linking or prompt users to sign in with their existing provider first.
The "account-exists-with-different-credential" error is thrown by Firebase Authentication when you have "Link accounts that use the same email" enabled in your Firebase console, and a user attempts to authenticate with an OAuth provider (Google, Facebook, GitHub, etc.) using an email address that is already associated with a different authentication provider in your project. Firebase uses email addresses as the unique identifier to link accounts across multiple providers, so this conflict occurs when the same email tries to use different providers.
First, verify your account linking configuration in Firebase Console:
1. Go to Firebase Console > Authentication > Settings
2. In the "User account linking" section, check your current setting:
- If "Link accounts that use the same email address" is enabled, this error can occur
- If "Create multiple accounts for each identity provider" is enabled, this error should not appear
Note: The setting determines how Firebase handles email conflicts. Enable "Link accounts" only if you want to enforce one account per email across all providers.
In your authentication code, add error handling for this specific error code and extract the AuthCredential from the error object:
For Firebase JS SDK v9+:
import { signInWithRedirect, getRedirectResult, GoogleAuthProvider } from 'firebase/auth';
try {
const result = await getRedirectResult(auth);
// Sign in successful
} catch (error) {
if (error.code === 'auth/account-exists-with-different-credential') {
// Extract the pending credential from the error
const pendingCredential = GoogleAuthProvider.credentialFromError(error);
// Get the email to display to user
const email = error.customData?.email;
// Prompt user to sign in with their existing provider
console.log('Account exists with different credential for:', email);
// Store pendingCredential for linking in next step
}
}For Flutter:
try {
final result = await FirebaseAuth.instance.signInWithPopup(googleProvider);
} on FirebaseAuthException catch (e) {
if (e.code == 'account-exists-with-different-credential') {
// Get the email associated with the account
final email = e.email;
// Get list of sign-in methods for this email
final methods = await FirebaseAuth.instance.fetchSignInMethodsForEmail(email!);
print('Sign-in methods available: $methods');
}
}Display a message to the user explaining the situation and guiding them to sign in with their existing provider:
const email = error.customData?.email;
const methods = await auth.fetchSignInMethodsForEmail(email);
// Example: methods might be ['facebook.com', 'password']
alert(`This email is already registered with ${methods.join(', ')}. Please sign in with that provider first.`);
// Redirect user to sign in with their existing provider
// Example: sign in with Facebook if that's their existing provider
const result = await signInWithPopup(auth, facebookProvider);,
Store the pending credential (from step 2) so you can link it after the user signs in with their existing provider.
After the user signs in with their existing provider, link the new provider using the stored pending credential:
For Firebase JS SDK v9+:
// After user successfully signs in with their existing provider
try {
// Link the pending credential (from the original sign-in attempt) to the current user
await linkWithCredential(auth.currentUser, pendingCredential);
console.log('Account linked successfully!');
} catch (error) {
console.error('Failed to link accounts:', error);
}For Flutter:
try {
// After signing in with existing provider, get user and link new provider
final facebookCredential = await FirebaseAuth.instance.signInWithPopup(facebookProvider);
await auth.currentUser?.linkWithCredential(googleAuthCredential);
print('Accounts linked!');
} catch (e) {
print('Link failed: ${e.message}');
}If you don't need to merge accounts across providers, you can simply disable account linking:
1. Go to Firebase Console > Authentication > Settings
2. Set "User account linking" to "Create multiple accounts for each identity provider"
3. Redeploy your app
With this setting, users can create separate accounts for each provider using the same email address. This eliminates the "account-exists-with-different-credential" error but prevents automatic account merging.
Pros: Simpler implementation, no custom linking logic needed
Cons: Users may accumulate multiple accounts with the same email
Known Issues and Workarounds:
1. Missing email in error object (Flutter, React Native): Some versions of Firebase SDKs don't include the email in the error object. Workaround: Use fetchSignInMethodsForEmail() with the email the user just tried to sign in with.
2. Inconsistent behavior between providers: Some OAuth flows (particularly signInWithRedirect) may not throw this error consistently depending on which provider is used first. Always implement proper error handling.
3. credential property undefined (v9 SDK): In some Firebase v9 implementations, error.credential is undefined. Use GoogleAuthProvider.credentialFromError(error) (or the appropriate provider class) instead.
4. FirebaseUI compatibility: If using FirebaseUI, ensure it's updated to handle account linking properly. Older versions may not properly resolve this error.
5. Testing locally: This error only occurs with "Link accounts" setting enabled. Test your flow both with and without account linking to ensure proper behavior.
messaging/UNSPECIFIED_ERROR: No additional information available
How to fix "messaging/UNSPECIFIED_ERROR: No additional information available" in Firebase Cloud Messaging
App Check: reCAPTCHA Score Too Low
App Check reCAPTCHA Score Too Low
storage/invalid-url: Invalid URL format for Cloud Storage reference
How to fix invalid URL format in Firebase Cloud Storage
auth/missing-uid: User ID identifier required
How to fix "auth/missing-uid: User ID identifier required" in Firebase
auth/invalid-argument: Invalid parameter passed to method
How to fix "auth/invalid-argument: Invalid parameter passed to method" in Firebase