Tại sao chọn Supabase?
Supabase là open-source alternative của Firebase, được xây dựng trên PostgreSQL. Với Supabase, bạn có ngay:
- PostgreSQL database với full SQL support
- Authentication (email, OAuth, magic link)
- File storage với CDN
- Realtime subscriptions
- Auto-generated REST và GraphQL API
- Row Level Security (RLS) để bảo vệ data
Setup dự án
Cài đặt dependencies cần thiết:
bash
npm install @supabase/supabase-js @supabase/ssrTạo file .env.local:
bash
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-keyTạo Supabase clients
Với Next.js App Router, bạn cần hai loại client khác nhau:
typescript
// lib/supabase/client.ts — dùng trong Client Components
import { createBrowserClient } from "@supabase/ssr"
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
}
// lib/supabase/admin.ts — dùng trong Server Components (bypass RLS)
import { createClient } from "@supabase/supabase-js"
export const supabaseAdmin = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
)Authentication với Email/Password
typescript
// Đăng ký
const { error } = await supabase.auth.signUp({
email: "user@example.com",
password: "password123",
options: {
data: { full_name: "Nguyen Van A" }
}
})
// Đăng nhập
const { data, error } = await supabase.auth.signInWithPassword({
email: "user@example.com",
password: "password123"
})
// Đăng xuất
await supabase.auth.signOut()Row Level Security (RLS)
RLS là tính năng quan trọng nhất của Supabase — nó cho phép bạn kiểm soát ai được đọc/ghi dữ liệu trực tiếp ở database level:
sql
-- Cho phép mọi người đọc bài viết đã publish
create policy "Public can read published posts"
on posts for select
using (published = true);
-- Chỉ owner mới được update
create policy "Owner can update own posts"
on posts for update
using (auth.uid() = user_id);Upload file lên Storage
typescript
const { data, error } = await supabase.storage
.from("images") // tên bucket
.upload("avatar.jpg", file, {
upsert: true,
contentType: "image/jpeg"
})
// Lấy public URL
const { data: { publicUrl } } = supabase.storage
.from("images")
.getPublicUrl("avatar.jpg")Kết luận
Supabase giúp bạn có một backend hoàn chỉnh trong vài phút. Điểm mạnh lớn nhất là PostgreSQL — bạn có full power của relational database thay vì bị giới hạn bởi NoSQL như Firebase. Kết hợp với Next.js 15, đây là stack lý tưởng cho cá nhân và startup muốn ship nhanh.
