Alright, folks, gather 'round for a tale of developer hubris and enlightenment! Picture this: yours truly, a seasoned Supabase user (or so I thought), strutting around like a peacock with my database skills. Then, one fateful day, I had a wild idea. "Hey," I said to myself, "why don't we take a gander at those dusty old docs?" And boy, oh boy, did the universe have a laugh at my expense! There, nestled in the pages I'd neglected like last year's New Year's resolutions, was the holy grail of local development with Supabase. It was as if the coding gods themselves were cackling, "Surprise, hotshot! You've been doing it wrong this whole time!" So, here I am, eating a generous slice of humble pie and sharing my newfound wisdom. Let this be a lesson to us all: sometimes, RTFM isn't just good advice—it's a comedy goldmine!
Supabase CLI
Install the Supabase CLI with the following command (refer to the docs 😭 for more options):
brew install supabase/tap/supabase
With that out of the way, since I am recently working on a react native app, I will try to explain with that in mind.
Setting up the project
- Create a new react native project and change directory into it
npx create-expo-app demo-app --template blank
cd demo-app
- Now comes the holy grail part, we will locally setup supabase:
Prerequisites:
- Docker
supabase init
This will setup a local postgres instance and a supabase project.
- Start the supabase project
supabase start
You get all supabase features locally with the studio UI too. Hey, this blew my mind when I first saw it.
This will start the supabase project and this will give you the following secrets:
EXPO_PUBLIC_SUPABASE_URL=http://localhost:54321
EXPO_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
EXPO_SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU
SUPABASE_JWT_SECRET=super-secret-jwt-token-with-at-least-32-characters-long
SUPABASE_DB_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
NEXT_PUBLIC_SITE_URL=http://localhost:3000
S3_ACCESS_KEY=625729a08b95bf1b7ff351a663f3a23c
S3_SECRET_KEY=850181e4652dd023b7a98c58ae0d2d34bd487ee0cc3254aed6eda37307425907
S3_REGION=local
S3_BUCKET=your-bucket-name
Yes, you can access my supabase at localhost:54321, feel free to poke around.
Setting up the database
Now we will play with two main things:
- Migrations
- Seeding the database
You will have a folder structure like this:
rest of expo project
supabase
|-- migrations
|-- seed.sql
Migrations
Migrations are used to make changes to the database schema. You can create a new migration by running the following command:
supabase migration new create_employees_table
This will create a new migration file in the migrations
folder.
Now inside the migration folder, you will have a file with the name of the migration and a timestamp. Open the file and write this sql:
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
phone VARCHAR(255) NOT NULL
);
Keep generating migrations file as you make changes to the database schema. This helps you to keep track of the changes and also helps you to rollback to a previous state if needed.
Seeding the database
In the seed.sql
file, you can add the data that you want to seed the database with. This is useful if you want to have some data to work with when you start building the app.
INSERT INTO employees (name, email, phone) VALUES
('John Doe', 'john.doe@example.com', '1234567890'),
('Jane Doe', 'jane.doe@example.com', '1234567890');
Now time to update the database with the new schema and seed the database with the data.
supabase db reset
This will pull the schema from the database and merge it with the local schema.
Now if for some reason you want to go to prod with your app, you can run the following command:
supabase login
supabase link --project-ref <project-id>
supabase db push
This will push the schema to the database.
Supabase Types
Supabase also provides a way to generate types for the database. This is useful if you want to have some cool autocomplete in your editor.
From Production, initialize the project and generate the types:
supabase gen types --lang=typescript --project-id "$PROJECT_REF" --schema public > database.types.ts
If locally, you can generate the types with the following command:
supabase gen types --lang=typescript --local > database.types.ts
This will generate a database.types.ts
file in the root of the project.
Now when you initialize the supabase client, just do this:
const supabase = createClient<Database>(process.env.EXPO_PUBLIC_SUPABASE_URL, process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY);
Now you can use the types in your code.
const { data, error } = await supabase
.from('employees')
.select('*')
.eq('id', 1);