Setting Up Auth in React Native Without Losing Your Mind
Most people start a React Native app with Firebase Auth because it's the thing they saw in a tutorial three years ago. Then they hit a wall when they need row-level security, real-time database queries tied to user sessions, or cost control that doesn't make their invoice look like a phone number. That's when Supabase comes up. The migration isn't clean, but it's doable. I'll walk through what actually works. The core idea is straightforward. You replace the Firebase SDK calls with Supabase's JavaScript client. You keep your user flows—email/password, OAuth providers, magic links—but the auth context moves from Google's backend to Supabase's PostgreSQL-backed system. What you gain is tight integration between your auth state and your database policies. What you lose is some of the convenience APIs that Firebase provides out of the box. Here's the practical setup. Install the dependencies.
npm install @supabase/supabase-js Create a wrapper component that initializes the client once. Do not initialize it inside a component render. You'll create a new client on every re-render and lose your session state.
Common Pitfalls I've Hit
The biggest issue is session persistence across app restarts. Supabase stores the session in memory by default. On iOS, when the app gets backgrounded aggressively, you can lose the session. On Android it's usually fine. The workaround is to use the built-in persistence option and also handle the onAuthStateChange event to restore state explicitly when the app comes back to foreground. I spent a day tracking down a bug where users were getting logged out randomly. Turns out Expo's development build was clearing AsyncStorage between hot reloads, and Supabase was relying on it for session recovery. Switching to a file-based persistence strategy fixed it, but you have to configure it properly in the Supabase client options. Another thing nobody warns you about: the difference between signInWithOAuth and the web redirect flow. If you're using Expo Go, OAuth flows break because Expo Go doesn't support custom URL schemes the same way a production build does. You need to set up a custom scheme in app.json and test on a real device or in a development build. Otherwise you'll stare at a blank screen and wonder why the callback never fires.
Get the Full Details

The Migration Path
If you're coming from Firebase, your current code probably looks like this. Import auth, call signInWithEmailAndPassword, listen to onAuthStateChanged. With Supabase it becomes signUp, signInWithPassword, and subscribeToAuthStateChange. The semantics are similar but the API shapes are different enough to trip you up. Email confirmation is another difference. Firebase sends confirmation emails through its own service with minimal configuration. Supabase uses AWS SES or a custom SMTP setup. If you're on the free tier, you get Supabase's built-in email provider with a sending limit. For a side project it's fine. For anything handling real users, set up your own SMTP. It takes about twenty minutes and saves you from hitting rate limits later. Row Level Security policies are where Supabase actually shines. In Firebase you write security rules in a completely separate language. In Supabase you write SQL policies on your tables. If a user can only read their own records, you write one policy and it applies everywhere—API, direct database, admin panels. This takes some getting used to if you're coming from Firestore rules, but it's more powerful once it clicks.
What Supabase Doesn't Do Well
Offline support is weaker than Firebase. Firestore has a first-class offline persistence layer. Supabase relies on your own caching layer or the React Query pattern. If your app needs to work fully offline, you'll need to build that yourself or use something like WatermelonDB on top. The mobile push notification story is also less mature. Firebase Cloud Messaging is baked in. With Supabase you'd set up Webhooks and connect them to a service like OneSignal or send notifications through your own backend. It's not hard, but it's an extra moving part you didn't have before. Cost scaling is generally better than Firebase's runaway bills, but their pricing model changed recently and it's easy to get surprised. Realtime subscriptions are metered per connection. If you have a dashboard with twenty concurrent users all watching the same channel, you pay for twenty connections, not one. Be aware of this if you're building anything with heavy realtime requirements.
Practical Code Example
Here's what a minimal auth setup looks like in practice. Import createClient from the Supabase package. Pass your project URL and anon key. Create a context provider that holds the supabase instance and the current session. Wrap your app with it. Use the supabase.auth.signInWithPassword method for login and supabase.auth.signUp for registration. Listen to auth state changes with onAuthStateChange. Handle the session object to determine if a user is logged in. For OAuth, use signInWithOAuth and pass the provider. Set the redirectTo URL to your custom scheme. Handle the deep link in your app entry point. Extract the auth token from the URL parameters and pass it to setSession on the supabase client. This part is where most people get stuck, so pay attention to the redirect URL configuration in both your Supabase dashboard and your app.

Database queries with auth context look like this. You don't pass the user ID manually. You set up a policy that reads auth.uid() from the JWT Supabase attaches to every request automatically. This means your query code stays clean and your security is enforced at the database level, not in your application logic.
When to Stick With Firebase
If your app is simple, you need offline-first capabilities, and you don't plan to do complex database operations tied to user identities, Firebase might still be the right call. The ecosystem is larger, the documentation is more abundant for beginners, and the mobile SDKs are more polished. Supabase is better when you want a relational database, when costs matter, and when you're comfortable writing SQL instead of JSON rules. I moved my last project from Firebase to Supabase primarily because the Firestore rules were becoming unmaintainable. We had fifty-something rules files and nobody could track which user segment each one applied to. Switching to SQL policies cut our security maintenance time by roughly eighty percent. The initial migration took about a week for a medium-complexity app, but the long-term payoff was real. Supabase's auth documentation has improved significantly but it's still not as thorough as Firebase's. You'll spend time reading GitHub issues and Stack Overflow threads to figure out edge cases. That's normal. Factor that into your timeline. Don't assume the documentation will give you every answer upfront.
There's also the matter of provider support. Firebase Auth supports a wider range of identity providers out of the box. If you need something obscure or proprietary, check Supabase's current list before committing. They add providers regularly but you might hit a gap.
