How to Set Up Supabase Auth in React Native
Supabase Auth in React Native with Expo: email, OAuth, magic link. Cookie-based sessions with @supabase/ssr. The setup that actually works in production.
Supabase Auth in React Native with Expo: email, OAuth, magic link. Cookie-based sessions with @supabase/ssr. The setup that actually works in production.
Supabase Auth in React Native. Email, OAuth, magic link. Production setup in 15 minutes.
Prerequisites
There are two Supabase clients. One works. One doesn't.
@supabase/ssr — Use this. Cookie-based sessions. Works on server and client.@supabase/supabase-js createClient — Never use this for auth. Uses localStorage. Doesn't work server-side.I wasted 4 hours on my first app using the wrong client. Don't repeat my mistake.
npx expo install @supabase/supabase-js @supabase/ssr
// lib/supabase-browser.ts
import { createBrowserClient } from '@supabase/ssr';
export const supabase = createBrowserClient(
process.env.EXPO_PUBLIC_SUPABASE_URL!,
process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY!
);
For Next.js API routes or server actions:
// lib/supabase-server.ts
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';
export async function getSupabaseServerClient() {
const cookieStore = await cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() { return cookieStore.getAll(); },
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
);
},
},
}
);
}
const { data, error } = await supabase.auth.signUp({
email: 'user@example.com',
password: 'securepassword',
});
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: 'yourapp://auth/callback',
},
});
For OAuth to work with Expo, you need deep linking configured in app.json:
{
"expo": {
"scheme": "yourapp"
}
}
After OAuth redirect, the URL contains tokens that need to be converted to cookies:
// TokenHandlerInBrowser.tsx
import { useEffect } from 'react';
import { supabase } from './supabase-browser';
export function TokenHandlerInBrowser() {
useEffect(() => {
supabase.auth.onAuthStateChange((event, session) => {
// Session is automatically managed via cookies
});
}, []);
return null;
}
Include this component in every layout that needs auth.
Server-side: always use await getSupabaseServerClient()
// Correct
const supabase = await getSupabaseServerClient();
const { data: { user } } = await supabase.auth.getUser();
// Wrong — will not have auth context
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(url, key);
Once auth is set up, enable Row Level Security on your tables:
ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can read own data"
ON your_table FOR SELECT
USING (auth.uid() = user_id);
This ensures users can only access their own data, regardless of what the application code does.
Everything in this guide is already pre-configured in AI App Factory. 11 AI agents automate the rest.