Supabase — Nền tảng Backend mã nguồn mở thay thế Firebase

Posted on: 4/27/2026 4:14:07 PM

101K+GitHub Stars
1M+Database đã tạo
$0Free tier trọn đời
SOC2 + HIPAACompliance chuẩn Enterprise

1. Supabase là gì và tại sao lại quan trọng?

Supabase là nền tảng phát triển backend mã nguồn mở, xây dựng hoàn toàn trên PostgreSQL — cơ sở dữ liệu quan hệ phổ biến nhất thế giới. Thay vì bị khóa vào hệ sinh thái đóng như Firebase (Google), Supabase cho phép bạn sở hữu toàn bộ dữ liệu, tự host khi cần, và di chuyển bất kỳ lúc nào.

Slogan của Supabase — "Build in a weekend, Scale to millions" — không phải quảng cáo suông. Với Supabase, bạn nhận được ngay lập tức: database, authentication, real-time subscriptions, storage, edge functions, vector embeddings, và RESTful APIs tự động — tất cả từ một dashboard duy nhất.

Tại sao chọn Supabase thay vì Firebase?

Firebase sử dụng Firestore (NoSQL proprietary) — mọi dữ liệu của bạn bị khóa trong Google Cloud. Supabase dùng PostgreSQL chuẩn: bạn có thể export, migrate, hoặc self-host bất kỳ lúc nào. Không vendor lock-in.

2. Kiến trúc tổng quan Supabase

Supabase không phải một monolithic service mà là bộ công cụ mã nguồn mở được ghép nối chặt chẽ. Mỗi thành phần đều có thể chạy độc lập.

graph TD
    A["Client App
(React, Vue, Flutter)"] --> B["API Gateway
Kong / Supabase Gateway"] B --> C["PostgREST
Auto REST API"] B --> D["GoTrue
Auth Service"] B --> E["Realtime
Elixir Server"] B --> F["Storage API
S3-compatible"] B --> G["Edge Functions
Deno Runtime"] C --> H["PostgreSQL
+ pgvector, PostGIS"] D --> H E --> H F --> I["Object Storage
(S3 / local)"] G --> H style A fill:#e94560,stroke:#fff,color:#fff style B fill:#2c3e50,stroke:#fff,color:#fff style C fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style D fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style E fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style F fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style G fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style H fill:#4CAF50,stroke:#fff,color:#fff style I fill:#16213e,stroke:#fff,color:#fff

Kiến trúc Supabase — mỗi thành phần là một dự án mã nguồn mở độc lập

Thành phầnCông nghệVai trò
PostgRESTHaskellTự động tạo RESTful API từ schema PostgreSQL
GoTrueGoAuthentication: email, OAuth, magic link, phone
RealtimeElixir/PhoenixBroadcast changes qua WebSocket từ PostgreSQL WAL
StorageNode.jsUpload/download files, tích hợp RLS
Edge FunctionsDenoServerless functions chạy ở edge, deploy globally
pg_graphqlRust extensionGraphQL endpoint tự động từ PostgreSQL schema
pgvectorC extensionVector embeddings cho AI/ML search

3. PostgreSQL — Trái tim của Supabase

Điểm khác biệt lớn nhất giữa Supabase và Firebase nằm ở nền tảng database. Supabase sử dụng PostgreSQL với đầy đủ sức mạnh:

  • Row Level Security (RLS) — kiểm soát truy cập ở tầng database, không phải tầng application
  • Foreign keys, joins, transactions — quan hệ dữ liệu chuẩn ACID
  • Extensions: pgvector (AI embeddings), PostGIS (geospatial), pg_cron (scheduled jobs), pg_stat_statements (monitoring)
  • Triggers và Functions — business logic chạy ngay trong database
  • Full-text search — tìm kiếm nhanh không cần Elasticsearch

3.1 Row Level Security — Bảo mật ở tầng sâu nhất

RLS là tính năng then chốt. Thay vì viết logic kiểm tra quyền trong application code (dễ bỏ sót), bạn định nghĩa policy trực tiếp trong PostgreSQL:

-- Chỉ cho phép user xem dữ liệu của chính họ
CREATE POLICY "Users can view own data"
ON profiles FOR SELECT
USING (auth.uid() = user_id);

-- User chỉ được update profile của mình
CREATE POLICY "Users can update own profile"
ON profiles FOR UPDATE
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);

-- Admin có thể xem tất cả
CREATE POLICY "Admins can view all"
ON profiles FOR SELECT
USING (
  EXISTS (
    SELECT 1 FROM user_roles
    WHERE user_roles.user_id = auth.uid()
    AND user_roles.role = 'admin'
  )
);

Tại sao RLS vượt trội hơn Firestore Security Rules?

Firestore Security Rules dùng cú pháp riêng, không thể test dễ dàng, và chỉ áp dụng cho Firestore. RLS của PostgreSQL dùng SQL chuẩn, áp dụng cho mọi cách truy cập — REST API, GraphQL, direct connection, Edge Functions — đảm bảo không có lỗ hổng nào bị bỏ sót.

4. Authentication toàn diện với GoTrue

Supabase Auth (GoTrue) hỗ trợ đầy đủ các phương thức xác thực:

  • Email + Password với email confirmation
  • Magic Link — đăng nhập không cần mật khẩu
  • OAuth 2.0 — Google, GitHub, Apple, Discord, Twitter, Azure AD, 20+ providers
  • Phone / SMS OTP
  • SAML 2.0 SSO — cho enterprise
  • Anonymous sign-in — cho phép thử app trước khi đăng ký
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)

// Đăng ký
const { data, error } = await supabase.auth.signUp({
  email: 'user@example.com',
  password: 'secure-password'
})

// Đăng nhập OAuth
const { data, error } = await supabase.auth.signInWithOAuth({
  provider: 'google',
  options: { redirectTo: 'https://myapp.com/callback' }
})

// Lấy thông tin user hiện tại
const { data: { user } } = await supabase.auth.getUser()

5. Realtime — Đồng bộ dữ liệu thời gian thực

Supabase Realtime server (viết bằng Elixir) lắng nghe PostgreSQL WAL (Write-Ahead Log) và broadcast thay đổi qua WebSocket tới tất cả client đang subscribe.

sequenceDiagram
    participant C1 as Client A
    participant RT as Realtime Server
    participant DB as PostgreSQL
    participant C2 as Client B

    C1->>RT: Subscribe channel "todos"
    C2->>RT: Subscribe channel "todos"
    C1->>DB: INSERT INTO todos (task)
    DB->>RT: WAL change event
    RT->>C1: Broadcast: new row
    RT->>C2: Broadcast: new row

Luồng Realtime: PostgreSQL WAL → Elixir Server → WebSocket → Clients

Ba loại Realtime events:

  • Postgres Changes — lắng nghe INSERT/UPDATE/DELETE trên bảng cụ thể
  • Broadcast — gửi message tự do giữa clients (chat, cursors, notifications)
  • Presence — theo dõi trạng thái online/offline của users
// Subscribe thay đổi trên bảng "messages"
const channel = supabase
  .channel('room-1')
  .on('postgres_changes',
    { event: 'INSERT', schema: 'public', table: 'messages' },
    (payload) => {
      console.log('New message:', payload.new)
    }
  )
  .on('presence', { event: 'sync' }, () => {
    const state = channel.presenceState()
    console.log('Online users:', Object.keys(state).length)
  })
  .subscribe()

// Broadcast cursor position
channel.send({
  type: 'broadcast',
  event: 'cursor',
  payload: { x: 100, y: 200, userId: 'abc' }
})

6. Edge Functions — Serverless trên Deno Runtime

Edge Functions là serverless functions chạy trên Deno runtime, deploy globally gần users. Sử dụng TypeScript/JavaScript, hỗ trợ npm packages qua npm: specifier.

// supabase/functions/process-payment/index.ts
import { serve } from "https://deno.land/std/http/server.ts"
import { createClient } from "npm:@supabase/supabase-js@2"
import Stripe from "npm:stripe@14"

serve(async (req: Request) => {
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
  )

  const { orderId, amount } = await req.json()

  // Verify order exists
  const { data: order } = await supabase
    .from('orders')
    .select('*')
    .eq('id', orderId)
    .single()

  if (!order) {
    return new Response(JSON.stringify({ error: 'Order not found' }), {
      status: 404
    })
  }

  // Process payment
  const stripe = new Stripe(Deno.env.get('STRIPE_KEY')!)
  const payment = await stripe.paymentIntents.create({
    amount: amount * 100,
    currency: 'usd'
  })

  // Update order status
  await supabase
    .from('orders')
    .update({ status: 'paid', payment_id: payment.id })
    .eq('id', orderId)

  return new Response(JSON.stringify({ success: true, payment_id: payment.id }))
})

Rate limit Edge Functions (tháng 3/2026)

Supabase đã giới hạn recursive/nested Edge Function calls: mỗi request chain có budget tối thiểu 5.000 requests/phút. Thiết kế functions tránh fan-out pattern quá sâu.

7. Storage — Lưu trữ file tích hợp RLS

Supabase Storage quản lý files (ảnh, video, documents) với S3-compatible backend. Điểm đặc biệt: Storage cũng sử dụng RLS — bạn kiểm soát ai được upload/download file nào bằng SQL policy.

// Upload file
const { data, error } = await supabase.storage
  .from('avatars')
  .upload(`${userId}/profile.jpg`, file, {
    cacheControl: '3600',
    upsert: true
  })

// Tạo signed URL (hết hạn sau 1 giờ)
const { data: { signedUrl } } = await supabase.storage
  .from('documents')
  .createSignedUrl('report.pdf', 3600)

// Public URL cho assets tĩnh
const { data: { publicUrl } } = await supabase.storage
  .from('public-images')
  .getPublicUrl('banner.jpg')

8. Vector Embeddings — AI/ML Search với pgvector

Với extension pgvector, PostgreSQL trở thành vector database — lưu trữ và tìm kiếm embeddings từ OpenAI, Hugging Face, Cohere ngay trong cùng database với dữ liệu business.

-- Tạo bảng lưu documents + embeddings
CREATE TABLE documents (
  id BIGSERIAL PRIMARY KEY,
  content TEXT,
  embedding VECTOR(1536)  -- OpenAI ada-002 dimension
);

-- Tạo index cho similarity search nhanh
CREATE INDEX ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

-- Tìm 5 documents tương tự nhất
SELECT id, content,
  1 - (embedding <=> '[0.1, 0.2, ...]'::vector) AS similarity
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, ...]'::vector
LIMIT 5;

Lợi thế so với vector database riêng

Dùng pgvector trong Supabase, bạn không cần thêm service riêng (Pinecone, Weaviate). Metadata filtering kết hợp SQL WHERE clauses mạnh mẽ hơn nhiều so với các vector-only databases.

9. So sánh Supabase vs Firebase

Tiêu chíSupabaseFirebase
DatabasePostgreSQL (quan hệ, ACID)Firestore (NoSQL, document)
Query languageSQL chuẩnSDK-specific queries
AuthGoTrue (20+ providers, SAML SSO)Firebase Auth (tương đương)
RealtimeWebSocket + PostgreSQL WALFirestore listeners
StorageS3-compatible + RLSCloud Storage + Security Rules
ServerlessEdge Functions (Deno)Cloud Functions (Node.js)
Vector Searchpgvector tích hợpCần thêm service (Vertex AI)
Pricing modelResource-based (dự đoán được)Per-operation (khó dự đoán)
Vendor lock-inKhông — self-host đượcCao — Google Cloud only
Offline supportHạn chếTốt (Firestore offline cache)
Open sourceCó (Apache 2.0)Không
Chi phí ở quy mô lớnRẻ hơn 30–50%Đắt hơn do per-read/write billing

10. Pricing — Free tier và chi phí thực tế

500 MBDatabase (Free)
1 GBFile Storage (Free)
50KMAU Auth (Free)
$25/moPro Plan
PlanDatabaseStorageBandwidthGiá
Free500 MB (shared CPU)1 GB5 GB$0
Pro8 GB (dedicated CPU)100 GB250 GB$25/tháng
Team8 GB + SOC2100 GB250 GB$599/tháng
EnterpriseCustomCustomCustomLiên hệ

11. Tích hợp với Vue.js — Ví dụ thực tế

Supabase có SDK chính thức hỗ trợ tất cả framework phổ biến. Dưới đây là ví dụ với Vue 3 Composition API:

// composables/useSupabase.ts
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  import.meta.env.VITE_SUPABASE_URL,
  import.meta.env.VITE_SUPABASE_ANON_KEY
)

export function useTodos() {
  const todos = ref([])
  const loading = ref(true)

  // Fetch initial data
  async function fetchTodos() {
    const { data } = await supabase
      .from('todos')
      .select('*')
      .order('created_at', { ascending: false })
    todos.value = data ?? []
    loading.value = false
  }

  // Realtime subscription
  const channel = supabase
    .channel('todos-changes')
    .on('postgres_changes',
      { event: '*', schema: 'public', table: 'todos' },
      (payload) => {
        if (payload.eventType === 'INSERT') {
          todos.value.unshift(payload.new)
        } else if (payload.eventType === 'DELETE') {
          todos.value = todos.value.filter(t => t.id !== payload.old.id)
        } else if (payload.eventType === 'UPDATE') {
          const idx = todos.value.findIndex(t => t.id === payload.new.id)
          if (idx !== -1) todos.value[idx] = payload.new
        }
      }
    )
    .subscribe()

  onMounted(fetchTodos)
  onUnmounted(() => supabase.removeChannel(channel))

  return { todos, loading }
}

12. Self-hosting — Kiểm soát hoàn toàn

Supabase hoàn toàn có thể self-host bằng Docker Compose. Đây là lợi thế lớn cho các tổ chức có yêu cầu compliance nghiêm ngặt hoặc muốn chạy on-premise:

# Clone và khởi chạy Supabase self-hosted
git clone https://github.com/supabase/supabase
cd supabase/docker
cp .env.example .env
# Chỉnh sửa .env: JWT_SECRET, POSTGRES_PASSWORD, ...
docker compose up -d

Stack self-hosted bao gồm: PostgreSQL, PostgREST, GoTrue, Realtime, Storage, Kong Gateway, Studio UI — tất cả chạy trong containers riêng biệt.

13. Khi nào nên chọn Supabase?

Chọn Supabase khi:

  • Dữ liệu có quan hệ phức tạp (orders → items → products → categories)
  • Cần SQL mạnh mẽ: joins, aggregations, window functions
  • Muốn kiểm soát dữ liệu, có thể migrate bất kỳ lúc nào
  • Cần vector search tích hợp cho AI features
  • Budget-conscious: pricing dự đoán được, free tier hào phóng
  • Compliance: cần self-host hoặc SOC2/HIPAA

Firebase có thể phù hợp hơn khi:

  • App mobile-first cần offline-first sync mạnh
  • Dữ liệu dạng document không cần quan hệ
  • Đã đầu tư sâu vào Google Cloud ecosystem
  • Cần Firebase ML Kit, Remote Config, Analytics tích hợp

14. Kết luận

Supabase đã chứng minh rằng backend-as-a-service không nhất thiết phải đánh đổi giữa tiện lợi và kiểm soát. Với PostgreSQL làm nền tảng, RLS cho bảo mật, Realtime cho đồng bộ, Edge Functions cho serverless, và pgvector cho AI — Supabase là lựa chọn mặc định cho hầu hết dự án mới trong năm 2026.

Đặc biệt với free tier 500 MB database + 50K MAU + unlimited API requests, bạn hoàn toàn có thể prototype và launch sản phẩm mà không tốn đồng nào.

Tham khảo