π Authentication
Shipnative uses Supabase for user authentication. This guide shows you how to add login, signup, and user management to your app.For AI Users: This entire guide is in the
vibe/ context files. You can ask your AI to βadd a profile screenβ or βimplement password resetβ and it will use these patterns automatically.π Quick Start (2 Minutes)
Want to start building auth features right away? You can skip all the setup! Shipnative works in mock mode by default - authentication works out of the box without any API keys.- β Login/signup screens already working
- β User sessions persisted
- β Password reset flows functional
- π¬ Mock mode indicator in dev menu
- When youβre ready to deploy
- When you need to test with real user data
- When building backend features (database, storage, realtime)
π Understanding Supabase Auth
Before diving into code, letβs understand how authentication works in Shipnative.How It Works
Key Concepts
Session: When a user logs in, Supabase creates a βsessionβ - think of it like a backstage pass that proves the user is authenticated. Secure Storage: The session is stored in your deviceβs secure storage (like a password manager built into iOS/Android). The user stays logged in even if they close the app. Row Level Security (RLS): Database rules that ensure users can only access their own data. Like a bouncer at a club checking IDs. Mock Mode: Simulated authentication that works without Supabase. Perfect for development!π― Using Authentication
The useAuth Hook (Recommended)
Shipnative provides a useAuth hook that makes authentication easy. Hereβs how to use it:
Common Authentication Tasks
Sign Up a New User
Sign Up a New User
- User enters email and password
- Supabase creates an account
- Sends confirmation email (in production)
- User clicks link to verify
- Account is active!
Log In with Email/Password
Log In with Email/Password
- βInvalid login credentialsβ = wrong email/password
- βEmail not confirmedβ = user hasnβt verified email
- Network errors = check internet connection
Log Out
Log Out
Reset Password
Reset Password
- User enters email
- Supabase sends password reset email
- User clicks link
- User enters new password
- Password is updated
Update User Profile
Update User Profile
user_metadata field in Supabase Auth. For storing additional profile data (bio, preferences, etc.), use the database (see Backend Guide).Social Login (Google, Apple)
Social Login (Google, Apple)
Check if User is Logged In
Check if User is Logged In
π οΈ Production Setup
Ready to add real Supabase authentication? Follow these steps.Skip if youβre just building: You can build your entire app with mock mode. Only set up real Supabase when youβre ready to deploy or need real user data.
Step 1: Create Supabase Project
- Go to supabase.com/dashboard/projects
- Click βNew projectβ
- Choose an organization (or create one)
- Set project name and database password
- Wait 2-3 minutes for provisioning
Step 2: Get API Credentials
- In your Supabase dashboard, go to Project Settings (βοΈ icon)
- Click API in the sidebar
- Copy your Project URL (looks like
https://abc123.supabase.co) - Copy your
anonpublic key (long string starting witheyJ...)
Step 3: Add to Your App
Openapps/app/.env and add:
Step 4: Set Up Database Schema
Your app needs a database to store user profiles and app data. Shipnative includes a ready-to-use schema.- In Supabase dashboard, go to SQL Editor
- Click βNew queryβ
- Open
shipnativeapp/supabase-schema.sqlfrom your project - Copy and paste the entire file
- Click βRunβ
profilestable - User profile info (name, avatar, etc.)user_preferencestable - App settings (dark mode, notifications, language)push_tokenstable - For push notifications- Row Level Security (RLS) policies - Data security rules
- Automatic triggers - Auto-create profile on signup
π Advanced: Row Level Security (RLS)
For AI Users: Security policies are documented in
vibe/SERVICES.md. Ask your AI to βadd a private posts featureβ and it will generate appropriate RLS policies.What is RLS?
Row Level Security ensures users can only access their own data. Without it, any user could read/modify anyoneβs data. Example: In a social app:- β Users can read all public posts
- β Users can only edit their own posts
- β Users canβt edit other peopleβs posts
- β Users canβt see private posts from others
How It Works
Example Policy
Letβs say you have aposts table:
auth.uid() means: The ID of the currently logged-in user. Supabase automatically knows whoβs making the request.
Common RLS Patterns
Testing RLS Policies
In Supabase SQL Editor, you can test policies:For more on RLS, see Supabase RLS Documentation
π§ͺ Direct Client Access (Advanced)
Most of the time, you should use theuseAuth hook. But sometimes you need direct access to the Supabase client.
Database Operations
Once you have auth set up, you can query your database:For complete database API, see Supabase JavaScript Client Docs
π§ͺ Mock Mode Features
When you build without Supabase API keys, Shipnative uses a mock Supabase client that simulates: Authentication:- β Sign up with email/password
- β Sign in with email/password
- β Sign out
- β Session persistence
- β Password reset (simulated)
- β User profile updates
- β Auth state listeners
- β
Select queries with filters (
eq,neq,gt,lt,like, etc.) - β Insert (single and multiple)
- β Update with filters
- β Delete with filters
- β Upsert
- β Ordering and pagination
- β Single row queries
π Troubleshooting
App still using mock mode in production
App still using mock mode in production
Symptoms: Console shows βπ [MockSupabase] Initialized mock Supabase clientβSolutions:
- Check that
apps/app/.envexists and has the correct values - Verify env vars start with
EXPO_PUBLIC_(required for Expo) - Restart Metro bundler:
yarn start --clear - Check for typos in env var names
- If using EAS Build, add env vars to
eas.jsonor environment secrets
User gets logged out on app restart
User gets logged out on app restart
Cause: Session isnβt being persisted to secure storageSolutions:
- Check that
persistSession: trueis set in Supabase client init - On iOS: Check Keychain permissions
- On Android: Check that app has storage permissions
- Check console for SecureStore errors
- Try uninstalling and reinstalling the app
Database queries return errors
Database queries return errors
Cause: Usually Row Level Security (RLS) blocking accessSolutions:
- Check Supabase dashboard logs (Authentication > Logs)
- Verify user is logged in (
auth.uid()is not null) - Check RLS policies in Supabase dashboard (Database > Tables > [table] > Policies)
- Make sure you ran
supabase-schema.sqlto set up policies - Test query in Supabase SQL Editor with
set role authenticated
Email confirmation not working
Email confirmation not working
Cause: Email templates not configured or email provider issueSolutions:
- In Supabase dashboard, go to Authentication > Email Templates
- Customize βConfirm signupβ template
- Check Authentication > Settings > Email Auth is enabled
- For development, disable email confirmation in Settings
- Check spam folder for confirmation emails
CORS errors on web
CORS errors on web
Cause: Supabase blocking web originSolutions:
- In Supabase dashboard, go to Project Settings > API
- Add your domain to βAllowed Origins (CORS)β
- Add
http://localhost:19006for local development - Add your production domain (e.g.,
https://yourapp.com) - Restart dev server after changes
'Invalid JWT' error
'Invalid JWT' error
Cause: Session token expired or corruptedSolutions:
- Log out and log back in
- Clear app data (uninstall/reinstall)
- Check that device clock is correct
- In Supabase dashboard, check JWT expiration settings