Supabase Configuration
This guide covers setting up Supabase for authentication and database.
Create a Project
- Go to supabase.com and sign in
- Click "New Project"
- Choose your organization
- Enter project details:
- Name: Your project name
- Database Password: Save this securely
- Region: Choose closest to your users
- Click "Create new project"
Wait for the project to be created (this takes a few minutes).
Get API Keys
- Go to Project Settings > API
- Copy these values to your
.env.local:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
Important: The service role key has admin privileges. Never expose it to the client!
Run Database Migrations
Option A: Using Supabase CLI (Recommended)
- Install the Supabase CLI:
# macOS
brew install supabase/tap/supabase
# npm
npm install -g supabase
- Log in and link your project:
supabase login
supabase link --project-ref your-project-ref
- Push migrations:
supabase db push
Option B: Manual SQL Execution
-
Go to SQL Editor in Supabase Dashboard
-
Run each migration file in order:
001_profiles.sql002_subscriptions.sql003_products.sql004_prices.sql005_rls_policies.sql
-
Optionally run
seed.sqlfor sample data
Enable Google OAuth
- Go to Authentication > Providers
- Find Google and enable it
- You'll need to create OAuth credentials in Google Cloud Console:
Google Cloud Setup
- Go to Google Cloud Console
- Create a new project or select existing
- Go to APIs & Services > OAuth consent screen
- Configure the consent screen
- Go to Credentials > Create Credentials > OAuth client ID
- Choose "Web application"
- Add authorized redirect URIs:
https://your-project.supabase.co/auth/v1/callback
- Copy the Client ID and Client Secret
Back in Supabase
- Paste the Client ID and Client Secret
- Save the provider settings
Configure Email Templates (Optional)
- Go to Authentication > Email Templates
- Customize the templates for:
- Confirm signup
- Magic Link
- Change Email Address
- Reset Password
Row Level Security (RLS)
Our migrations set up RLS policies for:
Profiles Table
- Users can view and update their own profile
- Service role can manage all profiles
Subscriptions Table
- Users can view their own subscriptions
- Service role can manage all subscriptions (webhooks)
Products & Prices Tables
- Anyone can view active products and prices
- Service role can manage products/prices
Database Schema
profiles
├── id (uuid, PK, FK to auth.users)
├── email (text)
├── full_name (text)
├── avatar_url (text)
├── stripe_customer_id (text, unique)
├── created_at (timestamptz)
└── updated_at (timestamptz)
subscriptions
├── id (uuid, PK)
├── user_id (uuid, FK to profiles)
├── stripe_subscription_id (text, unique)
├── stripe_price_id (text)
├── status (enum)
├── current_period_start (timestamptz)
├── current_period_end (timestamptz)
├── cancel_at_period_end (bool)
├── canceled_at (timestamptz)
├── trial_start (timestamptz)
├── trial_end (timestamptz)
├── created_at (timestamptz)
└── updated_at (timestamptz)
products
├── id (uuid, PK)
├── stripe_product_id (text, unique)
├── name (text)
├── description (text)
├── features (jsonb)
├── metadata (jsonb)
├── active (bool)
├── created_at (timestamptz)
└── updated_at (timestamptz)
prices
├── id (uuid, PK)
├── product_id (uuid, FK to products)
├── stripe_price_id (text, unique)
├── unit_amount (int)
├── currency (text)
├── interval (enum)
├── interval_count (int)
├── trial_period_days (int)
├── metadata (jsonb)
├── active (bool)
├── created_at (timestamptz)
└── updated_at (timestamptz)
Troubleshooting
"permission denied for table"
- Make sure RLS is enabled and policies are created
- Check that the service role key is set correctly for webhooks
Auth callback errors
- Verify the callback URL in Google OAuth settings
- Check that the Site URL in Supabase Auth settings is correct
Profile not created on signup
- The
on_auth_user_createdtrigger should create profiles automatically - Check the trigger exists in SQL Editor > Triggers