Prompt
duplicate accounts after social sign in
Latest observation
Oct 6, 2026
OpenAI APIWeb search: off
Duplicate accounts after social sign-in usually happen when the app creates a new user record for each provider login instead of linking the social identity to an existing account.
Common causes
- No account linking logic: Google/Facebook/etc. logins always create a new user.
- Email mismatch: The social provider email doesn’t match the email used for password sign-up.
- Provider IDs treated as separate users:
google_sub,facebook_id, etc. aren’t mapped to one internal user. - Race condition: Two sign-in flows happen at nearly the same time and both create accounts.
- Missing unique constraints: No DB uniqueness on email or provider identity mapping.
Recommended fix
1) Use one internal user table
Store a single users record per person, then a separate table for provider identities.
Example:
usersidemailname- ...
user_identitiesiduser_idprovider(google,facebook)provider_user_idemail(optional)
2) Link by verified email when safe
If a social provider returns a verified email, you can:
- search for an existing user by email
- if found, attach the new provider identity to that user
- otherwise create a new user
Be careful: only auto-link when the email is verified.
3) Enforce uniqueness
Add unique indexes such as:
users.emailunique (if your product allows one account per email)user_identities(provider, provider_user_id)unique
4) Make sign-in idempotent
The sign-in flow should:
- find identity by provider + provider user id
- if found, log in that user
- else check verified email for existing user
- else create new user and identity
- wrap in a transaction to avoid duplicates
If you already have duplicates
You’ll need an account merge process:
- choose a primary account
- reassign orders/data/roles to the primary user
- merge identities
- mark the duplicate account as merged or disabled
Example logic
identity = findIdentity(provider, provider_user_id)
if identity exists:
return identity.user
if verified_email exists:
user = findUserByEmail(verified_email)
if user exists:
createIdentity(user.id, provider, provider_user_id)
return user
user = createUser(email, name)
createIdentity(user.id, provider, provider_user_id)
return user
If you want, I can help you with:
- a database schema for account linking
- implementation in your stack (Firebase, Auth0, NextAuth, Supabase, Django, Rails, etc.)
- a merge strategy for existing duplicate accounts