RORK LABJP
TOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the roundTOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the round
Articles/Dev Tools
Dev Tools/2026-03-12Intermediate

Implementing User Authentication in Rork — Firebase & Supabase Integration Guide

Learn how to add user authentication to your Rork-built app using Firebase Authentication or Supabase Auth. A complete integration guide for React Native developers.

authentication4Firebase10Supabase33user managementloginsecurity5

Adding Authentication to Your Rork App

User authentication is a fundamental requirement for nearly every app. Because Rork generates React Native / Expo code, you can seamlessly integrate battle-tested authentication services like Firebase Authentication or Supabase Auth.

In this guide, we'll walk through two approaches to adding auth to a Rork-generated app:

  • Firebase Authentication — Deep Google ecosystem integration, excellent for social login
  • Supabase Auth — Open-source, PostgreSQL-native, developer-friendly API

Authentication Flow Overview

┌─────────────────────────────────────────────┐
│  App (Rork-generated code)                  │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐ │
│  │LoginScreen│→│ AuthHook │→│HomeScreen│ │
│  └──────────┘   └──────────┘   └──────────┘ │
│                       ↕                      │
│              Firebase / Supabase             │
└─────────────────────────────────────────────┘

Rork projects use Expo Router under the hood. The recommended pattern is to manage auth state in a custom hook, then use a root layout guard to redirect unauthenticated users to the login screen.


Using Firebase Authentication

1. Create a Firebase Project

In the Firebase Console, create a project and enable Email/Password under Authentication → Sign-in method. Download google-services.json (Android) and GoogleService-Info.plist (iOS) for later.

2. Rork Prompt Example

Add email and password authentication to the app.
- Create a login screen and a sign-up screen
- Use Firebase Authentication
- Only authenticated users can access the home screen
- Add a logout button to the profile screen

Rork will generate all the necessary code. You'll only need to swap in your Firebase configuration values.

3. Firebase Configuration

Add a firebase.config.js file to your Rork project:

// firebase.config.js
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
 
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_PROJECT.firebaseapp.com",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_PROJECT.appspot.com",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID",
};
 
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);

4. Auth Hook

// hooks/useAuth.js
import { useState, useEffect } from 'react';
import { onAuthStateChanged } from 'firebase/auth';
import { auth } from '../firebase.config';
 
export function useAuth() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
 
  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      setUser(currentUser);
      setLoading(false);
    });
    return () => unsubscribe();
  }, []);
 
  return { user, loading };
}

5. Login Screen

// app/login.jsx
import { useState } from 'react';
import { View, TextInput, Button, Text, StyleSheet } from 'react-native';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from '../firebase.config';
import { router } from 'expo-router';
 
export default function LoginScreen() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
 
  const handleLogin = async () => {
    try {
      await signInWithEmailAndPassword(auth, email, password);
      router.replace('/home');
    } catch (e) {
      setError('Invalid email or password. Please try again.');
    }
  };
 
  return (
    <View style={styles.container}>
      <TextInput
        placeholder="Email address"
        value={email}
        onChangeText={setEmail}
        keyboardType="email-address"
        autoCapitalize="none"
        style={styles.input}
      />
      <TextInput
        placeholder="Password"
        value={password}
        onChangeText={setPassword}
        secureTextEntry
        style={styles.input}
      />
      {error ? <Text style={styles.error}>{error}</Text> : null}
      <Button title="Log In" onPress={handleLogin} />
    </View>
  );
}
 
const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', padding: 20 },
  input: {
    borderWidth: 1, borderColor: '#ccc',
    borderRadius: 8, padding: 12, marginBottom: 12,
  },
  error: { color: 'red', marginBottom: 8 },
});

Using Supabase Auth

Supabase offers a simpler setup with excellent free-tier limits and native SQL support.

1. Create a Supabase Project

In the Supabase Dashboard, create a project, then go to Authentication → Providers and enable the Email provider. Note your Project URL and anon key.

2. Rork Prompt Example

Implement email authentication using Supabase.
- Send email verification on sign-up
- Login and logout functionality
- Redirect users based on auth state

3. Supabase Client Setup

// lib/supabase.js
import { createClient } from '@supabase/supabase-js';
import AsyncStorage from '@react-native-async-storage/async-storage';
 
export const supabase = createClient(
  'https://YOUR_PROJECT.supabase.co',
  'YOUR_ANON_KEY',
  {
    auth: {
      storage: AsyncStorage,
      autoRefreshToken: true,
      persistSession: true,
      detectSessionInUrl: false,
    },
  }
);

Important: Using AsyncStorage as the session storage ensures the user stays logged in after the app restarts.

4. Auth Hook (Supabase)

// hooks/useAuth.js
import { useState, useEffect } from 'react';
import { supabase } from '../lib/supabase';
 
export function useAuth() {
  const [session, setSession] = useState(null);
  const [loading, setLoading] = useState(true);
 
  useEffect(() => {
    supabase.auth.getSession().then(({ data: { session } }) => {
      setSession(session);
      setLoading(false);
    });
 
    const { data: { subscription } } = supabase.auth.onAuthStateChange(
      (_event, session) => setSession(session)
    );
 
    return () => subscription.unsubscribe();
  }, []);
 
  return { session, user: session?.user, loading };
}

5. Auth Operations

// Sign up
const { error } = await supabase.auth.signUp({
  email: 'user@example.com',
  password: 'securepassword',
});
 
// Log in
const { data, error } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'securepassword',
});
 
// Log out
await supabase.auth.signOut();

Route Guard: Redirect Unauthenticated Users

With Expo Router, implement a route guard in _layout.jsx:

// app/_layout.jsx
import { useEffect } from 'react';
import { Slot, router, useSegments } from 'expo-router';
import { useAuth } from '../hooks/useAuth';
 
export default function RootLayout() {
  const { user, loading } = useAuth();
  const segments = useSegments();
 
  useEffect(() => {
    if (loading) return;
 
    const inAuthGroup = segments[0] === '(auth)';
 
    if (!user && !inAuthGroup) {
      // Not logged in, trying to access protected screen → redirect to login
      router.replace('/(auth)/login');
    } else if (user && inAuthGroup) {
      // Already logged in, on auth screen → redirect to home
      router.replace('/home');
    }
  }, [user, loading, segments]);
 
  return <Slot />;
}

Firebase vs Supabase — Which Should You Choose?

FeatureFirebase AuthSupabase Auth
Free tier10,000 MAU/month50,000 MAU/month
Social login◎ (Google, Apple, Twitter, etc.)○ (major providers)
DatabaseFirestore (NoSQL)PostgreSQL (SQL)
Open source✗ (Google proprietary)
Learning curveMediumLow
Rork compatibility

For indie developers and MVPs, Supabase is the go-to choice — the free tier is generous and the API is intuitive. If Google/Apple Sign-In is a priority, Firebase is the more mature option.


Bonus: Adding Social Login

You can add social login with a simple prompt addition:

Also add Google Sign-In and Apple Sign-In buttons.
Use expo-auth-session for the implementation.

App Store Requirement: If your app offers any third-party login, Apple requires you to also offer Sign in with Apple. Don't skip this if you plan to ship on iOS.


Looking back

  • Rork generates React Native / Expo code, making it fully compatible with both Firebase and Supabase
  • Manage auth state centrally using a custom hook, then enforce it with a root layout guard
  • Choose Firebase for Google ecosystem depth; choose Supabase for open-source SQL flexibility
  • Always subscribe to onAuthStateChanged / onAuthStateChange for real-time auth state tracking

Adding authentication unlocks per-user data management, personalization, and a host of other features that elevate your app from a prototype to a real product. Give it a try in your next Rork project.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Dev Tools2026-06-21
Where Should Your Rork App Store Auth Tokens? expo-secure-store and a Biometric Gate
How I moved a Rork-generated app's auth tokens out of AsyncStorage into expo-secure-store and put a biometric check in front of every read — including the size limit and sign-out gotchas I hit in production.
Dev Tools2026-03-25
Rork × Supabase Auth & Realtime Guide — Building a Backend Without Code
Learn how to combine Rork with Supabase to implement authentication and real-time data sync. A practical step-by-step guide from user registration to real-time chat functionality.
Dev Tools2026-07-03
When Your App Store Connect API Pipeline Quietly Drops Days — Field Notes on JWT Expiry, Report Lag, and Reconciliation
Automated App Store Connect API pipelines rarely stop — they leak. This piece breaks down the three silent failure modes behind 401, 404, and 429, and shows how a fetch ledger, a 72-hour backfill window, and a weekly reconciliation query keep daily sales and review data complete.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →