DEV Community

Cathy Lai
Cathy Lai

Posted on

Google Sign In for React Native (via Supabase Auth): Overview

If you're building an MVP with Supabase + React Native, choosing the right authentication flow is critical. The easiest path is to use Supabase Auth with Google / Apple OAuth, which reduces friction and avoids building your own password system.

πŸ”‘ Overview of the Supabase Auth Setup

Your MVP typically has 3 main components:

  • Mobile App (React Native / Expo)
  • Supabase Auth + Database (Postgres)
  • Optional : Your own backend server (used if you want custom business logic)

Supabase handles OAuth (Google/Apple/Facebook), issues JWTs, and applies Row Level Security (RLS).


🟦 Step-by-Step: How the Login Flow Works

1. App Starts β†’ Check Existing Session

When the app launches:

const { data: session } = await supabase.auth.getSession();
Enter fullscreen mode Exit fullscreen mode
  • If session exists (with a valid JWT) β†’ user goes straight in.
  • If not β†’ show login screen.

2. User Taps β€œSign in with Google/Apple”

await supabase.auth.signInWithOAuth({
  provider: "google",
  options: { redirectTo: "your://callback" }
});
Enter fullscreen mode Exit fullscreen mode

This opens the provider’s login UI.


3. Provider Login

The user enters credentials with Google or Apple.


4. Provider Returns an Authorization Code

Important:

This code is not the JWT.

It is a temporary β€œticket” that must be exchanged.


5. Supabase Exchanges That Code for a Session Object

Supabase securely calls Google/Apple:

POST https://oauth2.googleapis.com/token  
β†’ returns: id_token, access_token, refresh_token
Enter fullscreen mode Exit fullscreen mode

Supabase then creates a session object:

{
  "access_token": "<JWT>",
  "refresh_token": "<long-lived token>",
  "user": { "id": "uuid", "email": "..." }
}
Enter fullscreen mode Exit fullscreen mode

βœ”οΈ The access_token is the JWT.

βœ”οΈ This is what your app will use for all authenticated actions.


6. Session Is Returned to Your App

The Supabase client stores and manages it.


πŸ”„ Token Refresh Flow (Handled Automatically)

  • The access_token (JWT) expires quickly.
  • The refresh_token silently fetches a new JWT.
  • Supabase handles this behind the scenes.

πŸ–₯️ Optional : Your Own Backend API

If your app calls a custom backend:

  1. The app sends requests with:
Authorization: Bearer <access_token>
Enter fullscreen mode Exit fullscreen mode
  1. Your backend verifies the Supabase JWT.
  2. Your backend runs custom logic and may call Supabase DB with a service role.

πŸ“‘ ASCII Diagram of the Full Flow

              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   Mobile App (RN)  β”‚
              β”‚  MyNextHome / MVP  β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
                       β”‚ 1. App start: check existing session
                       β”‚    
                       β–Ό
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚  No session? Show Login    β”‚
          β”‚  [Continue with Google]    β”‚
          β”‚  [Continue with Apple]     β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β”‚ 2. User taps "Google"
                   β”‚    
                   β–Ό
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚        Supabase Auth         β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚ 3. Redirect to provider
                    β–Ό
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚   Google / Apple / Facebook   β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚ 4. User authenticates
                   β–Ό
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚        Supabase Auth         β”‚
        β”‚ 5. Exchange code β†’ session   β”‚
        β”‚   Returns: access_token(JWT) β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚ 6. Session back to app
                    β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   Mobile App (RN)  β”‚
              β”‚ Stores session     β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚                   β”‚                         β”‚
  β”‚ 7a. Direct DB     β”‚ 7b. Custom Backend      β”‚
  β”‚     queries       β”‚     calls               β”‚
  β–Ό                   β–Ό                         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  (optional)
β”‚ Supabase DB    β”‚    β”‚ Your Backend    │─────────────┐
β”‚ + RLS          β”‚    β”‚ API Server      β”‚             β”‚
β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
      β”‚ Uses JWT (auth.uid())β”‚ Validates JWT          β”‚
      β–Ό                      β–Ό                        β–Ό
 Only user's data        Business logic             External APIs
Enter fullscreen mode Exit fullscreen mode

βœ… Summary

  • OAuth β†’ Provider returns authorization code
  • Supabase exchanges the code β†’ creates session (with JWT)
  • App stores session β†’ uses JWT for DB and backend access
  • Token refresh is automatic

This flow is ideal for an MVP because it’s simple, secure, and frictionless.

Top comments (0)