Supabase 开源后端:PostgreSQL 驱动的 Firebase 替代
Supabase 开源后端:PostgreSQL 驱动的 Firebase 替代
什么是 Supabase?
Supabase 是一个完全开源的 Firebase 替代品,它以企业级 PostgreSQL 数据库为核心,提供了一套完整的后端服务。你可以把它看作是“把 Firebase 的功能拆解成开源组件”的集合:
- PostgreSQL 数据库 —— 每创建一个 Supabase 项目,就得到一个完整的、标准的 PostgreSQL 实例。
- 认证 (Auth) —— 支持邮箱密码登录、魔术链接、第三方 OAuth(GitHub、Google 等)。
- 实时订阅 (Realtime) —— 通过 WebSocket 监听数据库变更,实现毫秒级实时推送。
- 文件存储 (Storage) —— 管理图片、视频等静态文件,并配合安全策略控制访问。
- 自动生成的 API —— Supabase 会根据数据库 Schema 自动生成 RESTful API 和 GraphQL 端点。
- 边缘函数 (Edge Functions) —— 无需自建服务器,使用 Deno 在边缘运行服务端逻辑(目前大部分功能已内置)。
关键就两个字:开源。你可以直接查看、修改源代码,甚至在自己的服务器上自托管整个 Supabase 堆栈,完全拥有数据和控制权。
为什么选择 Supabase?
| 对比维度 | Firebase | Supabase |
|---|---|---|
| 数据库 | NoSQL(Firestore) | 关系型 PostgreSQL |
| 开源 | 闭源 | 完全开源(MIT / Apache 2.0) |
| 自托管 | 不支持 | 支持 Docker 一键自托管 |
| 实时查询 | 客户端监听 | 数据库变更广播 + 客户端订阅 |
| SQL 能力 | 受限,需用客户端 SDK 拼查询 | 完整的 SQL 支持,视图、触发器、函数随意写 |
| 行级安全 | 安全规则(自定义语法) | PostgreSQL 原生 Row Level Security(标准 SQL) |
| 定价 | 按用量计费,容易失控 | 免费层慷慨,Project 化定价,成本可预测 |
对于习惯 SQL、重视数据关系的团队,Supabase 的学习曲线更加平缓;对于已经拥有 PostgreSQL 技能的用户,几乎可以直接上手。
快速开始:创建你的第一个 Supabase 项目
第一步:注册账号
访问 supabase.com ,点击 “Start your project”,你可以使用 GitHub 注册,整个过程免费。
第二步:新建项目
创建一个组织(个人或团队),然后点击 “New project”。你需要设置:
- 项目名称:比如
my-todo-app - 数据库密码:必须牢记,后续连接数据库会用到
- 区域:选择离用户最近的区域以减少延迟
- 定价计划:个人学习选免费的 “Free” 计划即可
等待一到两分钟,项目就绪后你会看到类似这样的仪表盘。

第三步:熟悉仪表盘主要模块
- Table Editor:可视化的表设计器,无需写 SQL 也能建表。
- SQL Editor:在线执行任何 SQL 语句,适合高级操作。
- Authentication:管理用户、启用登录方式。
- Storage:上传和管理文件。
- Edge Functions:编写无服务器函数(当前主要用数据库函数替代简单后端逻辑)。
接下来我们从最重要的部分开始——数据库。
数据库:强大的 PostgreSQL 核心
Supabase 的灵魂便是完整的 PostgreSQL。你的所有数据都存在标准的关系表中。
使用 Table Editor 创建第一张表
- 在仪表盘进入 Table Editor,点击 “New table”。
- 表名填写
todos,自动会生成一个id列(类型uuid,默认值gen_random_uuid())。 - 添加新列:
task:类型text,不允许为空(去掉 “Allow Nullable” 的勾)。is_complete:类型bool,默认值false。user_id:类型uuid,稍后用于与认证用户关联。
- 点击 “Save”。
此时你已经拥有了一张可以立刻使用的表。Supabase 会自动生成 REST API:
- 获取所有待办:
GET /rest/v1/todos - 插入一条数据:
POST /rest/v1/todos - 等等……我们马上会用客户端调用这些接口。
开启 Row Level Security(RLS)
为了安全,表默认是禁用公开访问的。你需要在 SQL Editor 中运行:
alter table todos enable row level security;
然后创建一条策略,让已登录用户只能操作自己的数据:
create policy "Individuals can manage their own todos."
on todos
for all
using ( auth.uid() = user_id )
with check ( auth.uid() = user_id );
auth.uid()是 Supabase 提供的函数,返回当前认证用户的 ID。- 这条策略保证用户只能读写
user_id等于自己 ID 的行。
认证系统:零摩擦管理用户
在左侧菜单进入 Authentication → Settings,你可以启用邮箱登录、魔术链接、手机验证(生产环境)以及第三方 OAuth。
启用邮箱登录
默认已开启 “Email” provider。确认开关处于打开状态,将 “Enable confirm email” 暂时关闭(开发时方便),然后保存。
用户注册与登录
使用 Supabase 的 JavaScript 客户端,只需几行代码:
<script type="module">
import { createClient } from 'https://cdn.jsdelivr.net/npm/@supabase/supabase-js/+esm'
const supabase = createClient(
'https://your-project-ref.supabase.co',
'your-anon-key'
)
// 注册
const { data, error } = await supabase.auth.signUp({
email: 'newuser@example.com',
password: 'supersecure',
})
</script>
这两个密钥在仪表盘的 Settings → API 中可以找到。anon key 是公开的,用于浏览器端安全调用;而 service_role key 必须仅用于服务器端,因为它可以绕过 RLS。
登录只需调用:
const { data, error } = await supabase.auth.signInWithPassword({
email: 'newuser@example.com',
password: 'supersecure',
})
第三方登录(GitHub 示例)
在 Authentication → Settings → External OAuth Providers,启用 GitHub,填写 Client ID 和 Secret。前端调用:
const { error } = await supabase.auth.signInWithOAuth({
provider: 'github',
})
用户授权后自动创建账户并返回,整个过程无需你写任何后端登录代码。
文件存储:轻松管理静态资源
进入 Storage,创建一个公开的存储桶(bucket)用于存放图片。
- 点击 “New bucket”,名称
avatars,勾选 “Public bucket” 使其可由公开 URL 访问。
上传文件:
const avatarFile = document.querySelector('#avatar').files[0]
const { data, error } = await supabase.storage
.from('avatars')
.upload(`public/${avatarFile.name}`, avatarFile)
如果需要私有文件,创建桶时不勾选 Public,然后通过 RLS 策略控制下载权限(通过 SQL 定义存储策略)。
实时功能:构建动态应用
Supabase 的 Realtime 功能可以监听表上的 INSERT、UPDATE、DELETE 事件,并推送给订阅的客户端。
首先,在 SQL Editor 中为需要监听的表启用实时:
alter publication supabase_realtime add table todos;
然后,前端订阅变更:
const channel = supabase
.channel('todos-changes')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'todos' },
(payload) => {
console.log('Change received!', payload.new)
// 根据 eventType 更新 UI
}
)
.subscribe()
现在,只要有用户在数据库中插入、更新或删除 todos,所有订阅者都会立即收到通知。
客户端库:用 JavaScript 快速开发
安装 SDK
你可以用 npm 安装:
npm install @supabase/supabase-js
或者在浏览器中直接通过 CDN 引入:
<script type="module">
import { createClient } from 'https://cdn.jsdelivr.net/npm/@supabase/supabase-js/+esm'
</script>
读取数据(结合认证)
假设用户已登录,我们希望只显示自己的待办事项。由于我们已经设置了 RLS 策略,查询会自动限定:
const { data: todos, error } = await supabase
.from('todos')
.select('*')
因为策略强制 user_id = auth.uid(),前端不需要传递任何额外条件。
插入数据
在创建任务时需要带上当前用户的 ID:
const user = supabase.auth.user()
const { error } = await supabase
.from('todos')
.insert({ task: '学习 Supabase', user_id: user.id })
更新与删除
// 将某个 todo 标记为完成
await supabase
.from('todos')
.update({ is_complete: true })
.eq('id', 'some-uuid')
// 删除
await supabase
.from('todos')
.delete()
.eq('id', 'some-uuid')
使用 SQL 函数
你可以在 Supabase 中创建自定义 PostgreSQL 函数,然后像调用 API 一样在客户端调用。例如,创建一个统计完成数量的函数:
create function completed_count()
returns bigint as $$
select count(*) from todos where is_complete = true and user_id = auth.uid();
$$ language sql stable;
前端调用:
const { data } = await supabase.rpc('completed_count')
console.log('已完成数量:', data)
自托管:将 Supabase 部署到你自己的服务器
开源除了透明性,最大好处是你可以完全拥有部署。Supabase 官方提供了 Docker 镜像及其组合,使用 docker-compose 可以一键启动全套服务。
-
克隆官方仓库:
git clone https://github.com/supabase/supabase cd supabase/docker -
复制环境变量文件并修改:
cp .env.example .env -
生成所需的 key:
docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml run --rm supabase-cli -
启动所有服务:
docker compose up -d
之后你就可以通过 http://localhost:8000 访问自己的 Supabase Studio,所有数据都留在你的机器上。这为数据敏感性较高的项目提供了完美的解决方案。
总结与下一步
Supabase 让你用熟悉的 PostgreSQL 获得媲美 Firebase 的开发体验,却不必被供应商锁定。对于初学者,推荐顺序如下:
- 阅读官方文档的 Quickstart(支持多种前端框架)
- 在 Supabase SQL Editor 中练习编写 SQL,尝试 RLS 策略
- 克隆官方示例 Todo List with Auth 并改造
- 探索自托管,理解其内部组件构成
开源后端的未来已经到来,Supabase 正在让每个开发者都能建造自己的 Firebase。现在就创建你的第一个项目,用一行 SQL 替代以往数小时的后端配置吧。