Estimated time: 15-20 minutes
This guide covers setting up Supabase as your database, authentication, and storage provider.
- Go to app.supabase.com
- Sign in with your Supabase account
- Click New Project
- Choose your organization (or create one)
- Fill in project details:
- Name: nutrisync (or your preferred name)
- Database Password: Click "Generate a password" and save it securely
- Important: Save this password - you'll need it for direct database access
- Store in a password manager or secure note
- Region: Select closest to your target users
- US East for Americas
- Europe West for Europe
- Southeast Asia for Asia/Pacific
- Click Create new project
- Wait 2-3 minutes for project initialization
Navigate to Project Settings > API:
Copy these three values:
- Project URL -
https://[project-ref].supabase.co - anon public - Long JWT token (safe for frontend)
- service_role - Long JWT token (backend only, keep secret)
Navigate to SQL Editor in Supabase dashboard (left sidebar).
Run each migration file from backend/migrations/ in sequential order. These migrations are idempotent (safe to re-run).
For each migration file:
- Open the file in your code editor
- Copy the entire contents
- In Supabase SQL Editor, paste the SQL
- Click Run (or press Ctrl/Cmd + Enter)
- Wait for success message
- Check for any errors before proceeding
- Proceed to next file
Migration Order (must be followed):
1. 001_setup_functions.sql # Creates helper functions
2. 002_user_management.sql # User profile and goals tables
3. 003_user_enhancements.sql # BMI, fiber, dietary restrictions
4. 004_weight_tracking.sql # Weight history tracking
5. 005_meal_tracking.sql # Meals and meal components
6. 006_meal_enhancements.sql # Photos, notes, custom foods
7. 007_achievements.sql # Daily achievement tracking
8. 008_fasting.sql # Fasting sessions
Note: If you see "relation already exists" warnings, these can be ignored - migrations are designed to be idempotent.
Verification After Each Migration:
- Navigate to Table Editor in sidebar
- Verify new tables appear as expected
- Check that RLS policies are created (view in Table Editor > [table] > Policies)
See backend/migrations/README.md for detailed migration documentation.
All tables are protected by Row Level Security (RLS) to ensure users can only access their own data. The migrations automatically create these policies, but you should verify them.
- Navigate to Table Editor in Supabase dashboard
- Select a table (e.g.,
meals,user_profile) - Click Policies tab at the top
- Verify "RLS enabled" badge is shown
Each table has 4 standard policies (SELECT, INSERT, UPDATE, DELETE):
Example for meals table:
- ✅ "Users can view own meals" -
SELECTusingauth.uid() = user_id - ✅ "Users can insert own meals" -
INSERTwith checkauth.uid() = user_id - ✅ "Users can update own meals" -
UPDATEusingauth.uid() = user_id - ✅ "Users can delete own meals" -
DELETEusingauth.uid() = user_id
Verify all 9 tables have RLS enabled with 4 policies each:
- user_profile - Personal details, BMI, dietary restrictions
- user_goals - Daily nutrition goals and fasting settings
- weight_history - Weight tracking over time (INSERT, UPDATE, SELECT only)
- meals - Meal logs with nutrition data
- meal_components - Individual foods within meals
- daily_achievements - Daily goal completion tracking
- fasting_sessions - Fasting start/end tracking
- user_foods - Custom user-created foods (RLS enabled via migration 006)
To verify RLS is working correctly:
- Create a test account in your app
- Add a meal or profile data
- In Supabase SQL Editor, try to query another user's data:
-- This should return ONLY your own meals, not other users' SELECT * FROM meals;
- The query uses the authenticated user's JWT, so you'll only see your data
What RLS Protects Against:
- ✅ Users accessing other users' meal logs
- ✅ Users modifying other users' goals
- ✅ Users viewing other users' photos
- ✅ Unauthorized API access to user data
See backend/migrations/README.md for detailed migration documentation.
- Navigate to Storage in Supabase dashboard
- Click New bucket
- Settings:
- Name:
meal-photos - Public bucket: Enable
- Name:
- Click Create bucket
Click on meal-photos bucket, go to Policies, add these three policies:
Allow uploads to own folder:
CREATE POLICY "Users can upload own photos"
ON storage.objects FOR INSERT
WITH CHECK (
bucket_id = 'meal-photos' AND
(storage.foldername(name))[1] = auth.uid()::text
);Allow viewing own photos:
CREATE POLICY "Users can view own photos"
ON storage.objects FOR SELECT
USING (
bucket_id = 'meal-photos' AND
(storage.foldername(name))[1] = auth.uid()::text
);Allow deleting own photos:
CREATE POLICY "Users can delete own photos"
ON storage.objects FOR DELETE
USING (
bucket_id = 'meal-photos' AND
(storage.foldername(name))[1] = auth.uid()::text
);Navigate to Authentication > Providers > Email:
- Enable email provider: On (enabled by default)
- Confirm email: Enable for production (recommended)
- Secure email change: Enable (recommended)
Email Delivery: Supabase handles all email sending (password resets, email verification, magic links). For development:
- Uses Supabase's default email service (rate-limited)
- Emails may go to spam folder
For production:
- Configure custom SMTP in Project Settings > Auth > SMTP Settings
- Or use Supabase's production email service (included in paid plans)
- Custom domain recommended for deliverability
See Production Considerations below for email and domain setup.
For "Sign in with Google" functionality, see Google OAuth Setup.
Navigate to Table Editor. You should see these tables:
- user_profile ✅ (RLS enabled)
- user_goals ✅ (RLS enabled)
- weight_history ✅ (RLS enabled)
- meals ✅ (RLS enabled)
- meal_components ✅ (RLS enabled)
- user_foods ✅ (RLS enabled)
- daily_achievements ✅ (RLS enabled)
- fasting_sessions ✅ (RLS enabled)
Navigate to Storage. You should see:
- meal-photos (bucket with 3 policies)
Security Checklist:
- ✅ All 9 tables have RLS enabled
- ✅ Each table has 4 policies (SELECT, INSERT, UPDATE, DELETE)
- ✅ Storage bucket has upload, view, and delete policies
- ✅ Email authentication is enabled
For production email reliability:
-
Purchase a domain (e.g., via Namecheap, Google Domains)
-
Configure DNS records for email authentication:
- SPF record for sender validation
- DKIM record for email signing
- DMARC record for reporting
-
Configure Supabase SMTP:
- Navigate to Project Settings > Auth > SMTP Settings
- Options:
- Use a service like SendGrid, AWS SES, or Resend
- Or upgrade to Supabase Pro for their production email service
-
Update email templates:
- Navigate to Authentication > Email Templates
- Customize confirmation, password reset, and magic link emails
- Use your domain in links
Not required for development, but recommended for production:
- Frontend: Configure in Vercel/Netlify (e.g.,
app.yourdomain.com) - Backend: Configure in Digital Ocean (e.g.,
api.yourdomain.com) - Update OAuth redirect URLs to use custom domain
See Deployment Guide for detailed DNS setup.
Development (works without custom domain):
- Supabase default email (limited sends, may go to spam)
- Default Supabase URLs for auth callbacks
- HTTP localhost URLs acceptable
Production (custom domain recommended):
- Custom SMTP for reliable email delivery
- Custom domain for professional appearance
- HTTPS required for OAuth and security
Next: API Configuration