"Supabase: Link Email to an Anonymous User in Flutter"
Link email to an anonymous Supabase user in Flutter — signInAnonymously(), updateUser() upgrades, linkIdentity OAuth, and the email-already-registered fix.
Forcing an email signup before someone has seen your app is the fastest way to lose them. Guest access converts — but only if the upgrade path doesn't nuke their data. The flow that actually works is to link email to an anonymous user in Flutter : keep the same user ID, the same rows, the same cart, and simply promote the guest into a permanent account. Supabase supports this natively with anonymous sign-ins plus updateUser() for email linking and linkIdentity() for OAuth. Yet most developers reach for signUp() when a guest registers — and silently orphan everything the guest created. This tutorial shows the correct conversion flow end to end. *Last updated: October 3, 2026* What you'll learn Why anonymous sign-in beats a login wall for activation How to enable anonymous sign-ins in the Supabase dashboard signInAnonymously() in Flutter and how to detect guest users Converting a guest to a permanent account with updateUser() (keeping the user ID) Linking Google/Apple to a guest session with linkIdentity() Handling the "email already registered" case without losing data Why signUp() on a guest session is a bug, not a feature Why Anonymous Sign-In Beats a Login Wall Anonymous auth gives every new user a real Supabase user row with a real auth.uid() — no fake sessions, no local-only hacks. That matters for two reasons: Row-level security just works. RLS policies keyed on auth.uid() apply to anonymous users too. A guest's data is already scoped to them from the first tap. Conversion preserves everything. When you link an email to that anonymous identity, the user ID never changes. No data migration, no orphaned rows, no "your guest progress was lost" apology screen. Anonymous users show up in your auth users table marked with is_anonymous: true . They count as…