Toolmingo
Guides12 min read

Supabase vs Firebase: Which Backend Platform Should You Use in 2025?

An in-depth comparison of Supabase and Firebase — database, auth, storage, real-time, pricing, open-source vs proprietary, and which to choose for your project in 2025.

Supabase and Firebase are the two most popular Backend-as-a-Service (BaaS) platforms, but they take fundamentally different approaches. Firebase is a proprietary Google platform built around NoSQL and a tightly integrated ecosystem. Supabase is an open-source alternative built on PostgreSQL that aims to give you the Firebase experience without the vendor lock-in.

At a glance

Supabase Firebase
Founded 2020 2011 (Google, 2014)
Open source Yes (Apache 2.0 / MIT) No (proprietary)
Database PostgreSQL (relational, SQL) Firestore (NoSQL, document)
Auth Built-in (GoTrue) Firebase Auth
Real-time PostgreSQL LISTEN/NOTIFY via WebSockets Firestore live queries / RTDB
Storage S3-compatible object storage Firebase Storage (GCS)
Functions Edge Functions (Deno) Cloud Functions (Node.js)
Self-hostable Yes (Docker) No
Free tier 2 projects, 500MB DB, 1GB storage Spark plan (generous limits)
Best for SQL-first apps, structured data, open-source priority Mobile apps, rapid prototyping, Google ecosystem

Architecture: PostgreSQL vs NoSQL

Supabase: PostgreSQL at the core

Supabase wraps PostgreSQL with a RESTful API (PostgREST), real-time subscriptions (Realtime server), auth (GoTrue), storage (Supabase Storage), and edge functions (Deno). Every feature is a thin layer on top of a standard Postgres database — which means you can connect directly with psql, run migrations, use ORMs, and write raw SQL.

-- In Supabase you write real SQL
SELECT
  users.name,
  COUNT(orders.id) AS order_count,
  SUM(orders.total) AS revenue
FROM users
LEFT JOIN orders ON orders.user_id = users.id
WHERE users.created_at > NOW() - INTERVAL '30 days'
GROUP BY users.id
ORDER BY revenue DESC;

Firebase: document-based NoSQL

Firebase's primary database is Firestore — a hierarchical, document-oriented NoSQL store. Data is organized into collections and documents. There is no SQL; queries are limited to a single collection (no cross-collection joins) and you must structure your data for the queries you need.

// Firebase Firestore — limited query capabilities
const ordersRef = db.collection('orders');
const snapshot = await ordersRef
  .where('userId', '==', userId)
  .where('status', '==', 'shipped')
  .orderBy('createdAt', 'desc')
  .limit(20)
  .get();

Database comparison

Feature Supabase (Postgres) Firebase (Firestore)
Query language Full SQL Firestore query API (no JOIN)
Joins Native SQL joins Must denormalize or do client-side
Transactions ACID, full multi-table Single-document and batch (limited)
Schema Strongly typed, enforced Schemaless (flexible but risky)
Indexes Auto + custom Auto + composite (must pre-define)
Full-text search tsvector/tsquery built-in Requires Algolia/Typesense integration
Vector search pgvector extension Not native
Relationships Foreign keys, referential integrity Manual, application-level
Migration tooling SQL migrations (Supabase CLI) No schema migrations
Max document/row size 1GB per row 1MB per document

Key insight: if your data is relational (users → orders → products), Supabase wins decisively. If your data is naturally hierarchical and document-shaped (e.g. chat messages nested under conversations), Firestore can be simpler.


Authentication

Both platforms provide email/password, magic links, OAuth (Google, GitHub, Apple, etc.), and phone/SMS auth out of the box.

Supabase Auth

import { createClient } from '@supabase/supabase-js';
const supabase = createClient(url, anon_key);

// Sign up
const { data, error } = await supabase.auth.signUp({
  email: 'user@example.com',
  password: 'supersecret',
});

// OAuth (Google)
await supabase.auth.signInWithOAuth({ provider: 'google' });

// Get current user
const { data: { user } } = await supabase.auth.getUser();

Firebase Auth

import { getAuth, signInWithEmailAndPassword, GoogleAuthProvider, signInWithPopup } from 'firebase/auth';
const auth = getAuth();

// Email/password
await signInWithEmailAndPassword(auth, 'user@example.com', 'supersecret');

// OAuth
const provider = new GoogleAuthProvider();
await signInWithPopup(auth, provider);

// Get current user
const user = auth.currentUser;

Differences:

  • Supabase uses JWT tokens stored in local storage; Firebase uses its own token system with an SDK.
  • Supabase Row Level Security (RLS) policies use auth.uid() directly in SQL — very powerful for database-level security.
  • Firebase Security Rules are a separate DSL that can feel verbose for complex data shapes.

Row Level Security vs Firebase Security Rules

This is where Supabase truly shines for data-heavy apps.

Supabase RLS (SQL-based)

-- Enable RLS
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;

-- Users can only read their own posts
CREATE POLICY "Users can view own posts"
  ON posts FOR SELECT
  USING (auth.uid() = user_id);

-- Users can insert their own posts
CREATE POLICY "Users can insert own posts"
  ON posts FOR INSERT
  WITH CHECK (auth.uid() = user_id);

Firebase Security Rules

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /posts/{postId} {
      allow read, write: if request.auth != null
        && request.auth.uid == resource.data.userId;
    }
  }
}

Supabase RLS rules live in the database itself and apply to every access path — REST API, direct SQL, and realtime subscriptions. Firebase rules apply to SDK access but not to Admin SDK calls (which bypass rules entirely).


Real-time subscriptions

Supabase Realtime

Supabase uses PostgreSQL's logical replication to stream database changes over WebSockets.

// Subscribe to all changes on the posts table
const channel = supabase
  .channel('public:posts')
  .on(
    'postgres_changes',
    { event: '*', schema: 'public', table: 'posts' },
    (payload) => {
      console.log('Change received:', payload);
    }
  )
  .subscribe();

// Broadcast (like a chat room, ephemeral)
const room = supabase.channel('chat-room');
room.on('broadcast', { event: 'message' }, ({ payload }) => {
  console.log(payload);
});
room.subscribe();

Firebase Firestore Real-time

import { onSnapshot, collection, query, where } from 'firebase/firestore';

const q = query(collection(db, 'posts'), where('authorId', '==', userId));

const unsubscribe = onSnapshot(q, (snapshot) => {
  snapshot.docChanges().forEach((change) => {
    if (change.type === 'added') console.log('New doc:', change.doc.data());
  });
});

Key differences:

  • Firebase Firestore real-time is battle-tested and used at scale by thousands of apps.
  • Supabase Realtime is newer and has had scaling improvements; it works well but is less mature.
  • For presence (who's online), Supabase Realtime Presence is excellent; Firebase RTDB is the classic choice.

Storage

Both offer file storage with direct upload from the browser.

Feature Supabase Storage Firebase Storage
Backend S3-compatible (MinIO self-hosted) Google Cloud Storage
Access control RLS-integrated storage policies Firebase Security Rules
Transforms Image resize/crop/webp on the fly Requires Cloud Functions
CDN Via Cloudflare (hosted) Google CDN
Direct upload Signed URLs, presigned uploads Firebase SDK or signed URLs
// Supabase Storage upload
const { data, error } = await supabase.storage
  .from('avatars')
  .upload(`${userId}/avatar.jpg`, file, { upsert: true });

// Get public URL
const { data: { publicUrl } } = supabase.storage
  .from('avatars')
  .getPublicUrl(`${userId}/avatar.jpg`);
// Firebase Storage upload
import { getStorage, ref, uploadBytes, getDownloadURL } from 'firebase/storage';
const storage = getStorage();
const storageRef = ref(storage, `avatars/${userId}/avatar.jpg`);
await uploadBytes(storageRef, file);
const url = await getDownloadURL(storageRef);

Serverless functions

Feature Supabase Edge Functions Firebase Cloud Functions
Runtime Deno (TypeScript) Node.js / Python
Deploy speed Fast (edge deploy ~30s) Slower (2+ minutes)
Cold starts Low (edge, globally distributed) Can be significant (Node.js)
Triggers HTTP, webhooks, database hooks (2024+) HTTP, Firestore events, Auth events, Pub/Sub, Scheduler
Ecosystem npm imports via CDN / JSR Full npm ecosystem
Testing locally supabase functions serve Firebase Emulator Suite
Pricing 2M invocations/month free 2M invocations/month free (Blaze plan)

Firebase wins on trigger variety; Supabase wins on cold start performance.


Pricing comparison

Free tiers

Resource Supabase Free Firebase Free (Spark)
Projects 2 (paused after 7 days inactivity) 1 project
Database 500MB Postgres N/A (charged per read/write)
Firestore reads N/A 50k/day
Firestore writes N/A 20k/day
Auth users 50,000 MAU Unlimited
Storage 1GB 5GB
Function invocations 500K/month 2M/month
Bandwidth 5GB 10GB/month

Paid tiers

Supabase Pro starts at $25/month for 2 projects with 8GB database, 100GB storage, 250GB bandwidth.

Firebase pricing is usage-based with no fixed monthly fee — it can be cheaper at low scale but becomes unpredictable at high read/write volumes. A busy Firestore app can generate surprisingly large bills.

Key insight: Firebase's usage-based model can be dangerous for viral apps. Supabase's fixed pricing is more predictable for production workloads.


Open source and self-hosting

Supabase Firebase
Open source Yes (all components on GitHub) No
Self-hostable Yes (Docker Compose, Kubernetes) No
Vendor lock-in Low (standard Postgres underneath) High (proprietary SDK, Firestore format)
Data portability Easy (pg_dump) Harder (Firestore export to JSON)
Community Growing (65k+ GitHub stars) Large but proprietary
# Self-host Supabase with Docker
git clone --depth 1 https://github.com/supabase/supabase
cd supabase/docker
cp .env.example .env
# edit .env with your secrets
docker compose up -d

Where Supabase wins

Scenario Why Supabase
Relational data SQL joins, foreign keys, referential integrity
Complex queries Aggregations, CTEs, window functions
AI/vector search pgvector extension built-in
Open source priority Apache 2.0 licensed, self-hostable
Predictable costs Fixed monthly pricing
Existing Postgres experience No new query language to learn
Full-text search Native tsvector/tsquery
Data migrations SQL migration files, version-controlled
Compliance/GDPR Self-host in your own region/cloud

Where Firebase wins

Scenario Why Firebase
Mobile apps (Android/iOS) Mature SDKs, offline support (Firestore)
Google Cloud ecosystem Native integration with GCP, BigQuery
Offline-first apps Firestore offline persistence is best-in-class
Rapid prototyping No schema to define, just write documents
Push notifications FCM (Firebase Cloud Messaging) is the standard
Analytics Firebase Analytics, Crashlytics, A/B Testing
A/B testing & Remote Config No equivalent in Supabase
Large ecosystem maturity Firebase has been production-tested for 10+ years
Firestore scale Automatic multi-region replication, 1M+ concurrent

Code example: building a todo app

Supabase

// supabase/types.ts (auto-generated)
type Todo = { id: number; text: string; done: boolean; user_id: string };

// Fetch todos (RLS enforces user_id = auth.uid())
const { data: todos } = await supabase
  .from('todos')
  .select('*')
  .order('created_at', { ascending: false });

// Insert
await supabase.from('todos').insert({ text: 'Buy milk', user_id: user.id });

// Update
await supabase.from('todos').update({ done: true }).eq('id', todoId);

// Real-time subscription
supabase
  .channel('todos')
  .on('postgres_changes', { event: '*', schema: 'public', table: 'todos' }, handleChange)
  .subscribe();

Firebase

// Fetch todos (Security Rules enforce uid == userId)
const todosRef = collection(db, 'users', user.uid, 'todos');
const snapshot = await getDocs(query(todosRef, orderBy('createdAt', 'desc')));
const todos = snapshot.docs.map(d => ({ id: d.id, ...d.data() }));

// Add
await addDoc(todosRef, { text: 'Buy milk', done: false, createdAt: serverTimestamp() });

// Update
await updateDoc(doc(todosRef, todoId), { done: true });

// Real-time
const unsubscribe = onSnapshot(todosRef, (snapshot) => {
  const todos = snapshot.docs.map(d => ({ id: d.id, ...d.data() }));
  setTodos(todos);
});

Full comparison

Feature Supabase Firebase
Database model Relational (PostgreSQL) Document (Firestore) + RTDB
Query power Full SQL, joins, CTEs Limited, no cross-collection joins
Transactions Full ACID Single-doc + batched writes
Schema Strict + typed Flexible (schemaless)
Auth GoTrue (JWT) Firebase Auth
Social login providers 20+ 20+
Real-time Postgres LISTEN/NOTIFY Firestore live queries
Offline support No (coming) Yes (Firestore SDK)
Storage S3-compatible Google Cloud Storage
Image transforms Yes (built-in) Via Cloud Functions
Serverless Edge Functions (Deno) Cloud Functions (Node/Python)
Triggers HTTP + DB hooks HTTP + many event types
Open source Yes No
Self-hostable Yes No
Vendor lock-in Low High
Free tier 500MB Postgres Per-read/write model
Pricing model Fixed monthly Usage-based
Predictable costs Yes Can spike unexpectedly
Push notifications Via third party FCM (best-in-class)
Analytics Via third party Firebase Analytics
A/B testing Via third party Remote Config
TypeScript types Auto-generated from schema Manual or converters
Local development Supabase CLI + local Docker Firebase Emulator Suite
Postgres extensions Yes (pgvector, PostGIS, etc.) N/A
GitHub stars 65k+ N/A (proprietary)

Decision guide

Do you need SQL / relational data or complex queries?
  └─ Yes → Supabase

Do you need Firestore offline persistence on mobile?
  └─ Yes → Firebase

Do you need push notifications (FCM)?
  └─ Yes → Firebase (use FCM regardless of BaaS)

Is open source / self-hosting required?
  └─ Yes → Supabase

Are you already in the Google Cloud / GCP ecosystem?
  └─ Yes → Firebase (native integrations)

Do you want predictable, fixed monthly pricing?
  └─ Yes → Supabase

Do you need AI / vector search (pgvector)?
  └─ Yes → Supabase

Are you building a document-heavy mobile app with offline first?
  └─ Yes → Firebase

Are you a SQL developer moving to BaaS?
  └─ Yes → Supabase (familiar paradigm)

Default for new web SaaS projects → Supabase
Default for mobile + Google ecosystem → Firebase

Common mistakes

Mistake Better approach
Using Firebase Firestore for highly relational data Switch to Supabase Postgres
Ignoring Supabase RLS — using service role key in the browser Always use anon key + RLS policies
Not pre-defining Firestore indexes for compound queries Add composite indexes before production
Forgetting Firebase pricing caps on Spark plan Move to Blaze plan before you need it
Fetching entire Firestore collections for aggregations Use Firestore aggregation queries (2023+) or Cloud Functions
Storing binary blobs in Firestore documents Use Firebase Storage / Supabase Storage instead
Not setting up Supabase pausing (free tier projects pause after 7 days) Upgrade or ping the project periodically
Using Firebase Admin SDK in client code (bypasses security rules) Use Admin SDK only in server/Cloud Functions

FAQ

Can I migrate from Firebase to Supabase? Yes, but it takes effort. Export Firestore data as JSON, then transform and import it into Postgres. Auth users can be exported from Firebase and imported via Supabase's admin API. File storage is a direct copy. There's no automated migration tool as of 2025, but the community has shared scripts.

Can I use both Supabase and Firebase in the same project? Yes. A common pattern is Supabase for the relational database and Firebase Cloud Messaging (FCM) for push notifications — FCM is best-in-class and has no direct Supabase equivalent.

Is Supabase production-ready? Yes. Supabase GA (Generally Available) was announced in 2023. Companies like Pebblely, Quivr, and many others run production workloads. However, Firebase has a longer track record at extreme scale.

Does Supabase work with React Native / mobile? Yes. The @supabase/supabase-js SDK works in React Native with AsyncStorage. Offline support is limited compared to Firestore's built-in offline persistence.

What about Next.js or Remix — which BaaS integrates better? Both integrate well with Next.js/Remix. Supabase has first-class Next.js App Router support via @supabase/ssr. Firebase has a Next.js SDK as well. For server components and server-side rendering, Supabase's SQL-backed approach is often simpler to reason about.

Is Firebase going away? No signals from Google suggest Firebase is being deprecated. However, Google has a history of sunsetting products (Firebase RTDB is in maintenance mode, replaced by Firestore). Supabase's open-source model means you're not dependent on a single vendor's roadmap.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools