Build a Real-time CRUD Application with Supabase
Introduction
Supabase is an open-source alternative to Firebase that provides a powerful PostgreSQL database, authentication, and real-time subscriptions. In this tutorial, we'll walk through building a simple real-time CRUD (Create, Read, Update, Delete) application with authentication.
Prerequisites
Before we begin, make sure you have:
- Node.js installed on your machine
- A Supabase account (free tier is fine)
- Basic knowledge of JavaScript/TypeScript
- Your favorite code editor
Setting Up Supabase
First, let's create a new Supabase project and set up our development environment.
1. Create a New Supabase Project
- Go to supabase.com and sign in
- Click "New Project" and fill in your project details
- Wait for your database to be provisioned (usually takes about 1 minute)
2. Install Supabase Client
In your project directory, install the Supabase client library:
npm install @supabase/supabase-js
3. Initialize Supabase Client
Create a new file called supabaseClient.js
:
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'YOUR_SUPABASE_URL'
const supabaseKey = 'YOUR_SUPABASE_ANON_KEY'
export const supabase = createClient(supabaseUrl, supabaseKey)
Database Setup
Let's create a simple todos table in Supabase:
create table todos (
id uuid default uuid_generate_v4() primary key,
user_id uuid references auth.users,
task text not null,
is_complete boolean default false,
created_at timestamp with time zone default timezone('utc'::text, now())
);
-- Enable Row Level Security (RLS)
alter table todos enable row level security;
-- Create policy to allow users to only see their own todos
create policy "Users can only access their own todos" on todos
for all using (auth.uid() = user_id);
Implementing Authentication
Supabase provides built-in authentication. Here's how to implement sign-up and sign-in:
// Sign up a new user
async function signUp(email, password) {
const { data, error } = await supabase.auth.signUp({
email,
password,
})
return { data, error }
}
// Sign in an existing user
async function signIn(email, password) {
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
})
return { data, error }
}
// Sign out
async function signOut() {
const { error } = await supabase.auth.signOut()
return { error }
}
CRUD Operations
Here's how to perform basic CRUD operations with Supabase:
// Create a new todo
async function createTodo(task) {
const { data, error } = await supabase
.from('todos')
.insert([{ task, user_id: supabase.auth.user().id }])
.select()
return { data, error }
}
// Read todos
async function getTodos() {
const { data, error } = await supabase
.from('todos')
.select('*')
.order('created_at', { ascending: false })
return { data, error }
}
// Update a todo
async function updateTodo(id, updates) {
const { data, error } = await supabase
.from('todos')
.update(updates)
.match({ id })
return { data, error }
}
// Delete a todo
async function deleteTodo(id) {
const { error } = await supabase
.from('todos')
.delete()
.match({ id })
return { error }
}
Real-time Subscriptions
One of Supabase's powerful features is real-time subscriptions. Here's how to implement them:
// Subscribe to changes in the todos table
const todosSubscription = supabase
.channel('todos')
.on('postgres_changes',
{ event: '*', schema: 'public', table: 'todos' },
(payload) => {
console.log('Change received!', payload)
// Handle the change here (e.g., update UI)
}
)
.subscribe()
Live Demo
Try out the real-time todo application below:
Authentication Demo
Todo List Demo
Best Practices and Tips
- Always implement Row Level Security (RLS) policies
- Use TypeScript for better type safety
- Handle errors appropriately
- Clean up subscriptions when components unmount
- Use environment variables for sensitive information
Conclusion
Supabase provides a powerful and developer-friendly platform for building real-time applications. With its PostgreSQL database, built-in authentication, and real-time subscriptions, you can quickly build sophisticated applications without managing complex infrastructure.
For more information, check out the following resources: