Skip to content

Realtime、Storage 与 Edge Functions

基于 Supabase · 核于 2026-08

速查

  • Realtime:基于 WebSocket 的实时推送。订阅三类事件——Postgres Changes(表增删改)、Presence(谁在线)、Broadcast(客户端间广播)。
  • Postgres Changes 原理:表变更产生 WAL(Write-Ahead Log),Realtime 服务(Elixir/Phoenix Channels)通过逻辑复制消费 WAL,转成事件推给订阅的客户端。
  • 订阅粒度:可订阅全表 postgres_changes(event='*'),也可过滤到具体行(filter=id=eq.1)和事件类型(INSERT/UPDATE/DELETE)。
  • Presence:跟踪"谁在线"——客户端心跳上报状态,服务端维护在线列表,断线自动剔除。聊天/协作里展示在线成员。
  • Broadcast:客户端之间低延迟广播消息(不必落库),适合鼠标位置、临时通知。
  • StorageS3 兼容的对象存储(图片/视频/PDF/任意文件),底层用 AWS S3 或自托管(基于 S3 协议)。
  • Storage 的 RLS:存储桶(bucket)和对象的访问也由 RLS 策略控制——上传/下载鉴权和数据库行级权限用同一套机制,不再是另写一套对象存储 ACL。
  • Edge Functions:基于 Deno 运行时的无服务器函数,部署在全球 CDN 边缘节点(Deno Deploy),靠近用户执行,TypeScript 原生。
  • Edge Functions 用途:Webhook、第三方 API 调用(绕过 CORS/密钥)、定时任务(Cron)、聚合查询、Stripe 集成。
  • 定价亮点:免费层无限 API 请求(不计调用次数)、500MB 数据库、1GB 存储、50k 月活用户、500MB Edge Functions 流量、2 个免费项目。
  • 进阶顺序:本叶讲实时/存储/函数 → 参考(对比表/定价/易错点)。

一、Realtime:订阅 Postgres 变更

Supabase Realtime 让前端"数据一变,界面就更新",无需轮询。它由三块组成:

1. Postgres Changes(数据变更)

订阅某张表的增删改:

js
supabase
  .channel('todos-changes')
  .on(
    'postgres_changes',
    { event: '*', schema: 'public', table: 'todos', filter: 'user_id=eq.10' },
    (payload) => console.log('变更:', payload)
  )
  .subscribe();

原理

客户端 UPDATE todos SET done=true WHERE id=1
   → Postgres 写 WAL(逻辑复制需开启 replica identity)
   → Realtime 服务(Elixir/Phoenix Channels)消费 WAL
   → 转成 { eventType, table, oldRecord, newRecord } 事件
   → 通过 WebSocket 推给所有订阅该表/该行的客户端
  • filter:可按列过滤(如只订阅自己的 todo),减少无关推送。
  • Replica Identity:要拿到 UPDATE/DELETE 的旧值(oldRecord),表需设 REPLICA IDENTITY FULL(默认只记主键)。
  • 权限:Realtime 推送同样受 RLS 约束——客户端只能收到它有权读的行的变更。
  • 吞吐上限:免费层每秒事件数有上限;高并发(如万人协作)要升级或自己分片。

2. Presence(在线状态)

js
const channel = supabase.channel('room-1', {
  config: { presence: { key: user.id } },
});
channel.on('presence', { event: 'sync' }, () => {
  const state = channel.presenceState(); // 当前在线用户
});
channel.subscribe(async (status) => {
  if (status === 'SUBSCRIBED') await channel.track({ name: user.name });
});

客户端定期心跳上报状态,服务端聚合在线列表并同步给所有人;断线超时自动剔除。用于聊天室在线成员、协作编辑光标。

3. Broadcast(消息广播)

客户端之间直接广播消息,不必落库

js
channel.on('broadcast', { event: 'cursor' }, ({ payload }) =>
  drawCursor(payload)
);
await channel.send({ type: 'broadcast', event: 'cursor', payload: { x, y } });

适合鼠标位置、临时通知等"过时即丢"的瞬时数据。

二、Storage:S3 兼容且受 RLS 保护

Supabase Storage 是对象存储(存图片/视频/PDF/任意二进制),两个关键特性:

1. S3 兼容

  • 底层可用 AWS S3(官方云)或自托管 S3 协议存储;API 兼容 S3,能用 aws-sdk/rclone 直接操作。
  • 组织成 bucket(桶)→ 对象。桶分 public(公开读)和 private(需鉴权)。

2. 由 RLS 策略保护

最特别的一点:Storage 的访问鉴权用和数据库同一套 RLS 机制。Storage 内部有 storage.buckets / storage.objects 表,对这些表写策略即可:

sql
-- 用户只能读写自己前缀下的对象
create policy "用户自己的文件"
  on storage.objects for all
  using (
    bucket_id = 'avatars'
    and (storage.foldername(name))[1] = auth.uid()::text
  );

效果:前端 supabase.storage.from('avatars').list() 只返回当前用户有权读的对象——文件权限和行权限统一,这是 Firebase Storage 的 Security Rules 之外、Supabase 把权限收口到 Postgres 一层的体现。

js
// 上传
await supabase.storage.from('avatars').upload(`${user.id}/face.png`, file);
// 下载(私有桶生成限时签名 URL)
const { data } = supabase.storage.from('avatars').createSignedUrl(path, 60);
// public 桶直接拼公开 URL
  • Public 桶:对象有公开 URL,任何人能读(如网站静态图)。
  • Private 桶:每次下载生成签名 URL(限时),或经 SDK 带 JWT 下载。
  • 变换(Transformations):官方云支持图片实时变换(缩放/裁剪/格式转换),按 URL 参数 ?width=200

三、Edge Functions:Deno 全球边缘

Edge Functions 是 Supabase 的无服务器函数,三个要点:

1. 基于 Deno,全球边缘

  • 运行时是 Deno(不是 Node)——TypeScript 原生、用 URL 导入依赖、启动快。
  • 部署在 Deno Deploy 的全球 CDN 边缘节点(全球 30+ 区域),请求就近处理——比 AWS Lambda 的"区域集中"延迟更低。
  • 冷启动快(毫秒级,远低于 Lambda 的百毫秒级)。

2. 典型用途

ts
// deno 标准库 + Supabase SDK
import { serve } from 'https://deno.land/std/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js';

serve(async (req) => {
  const supabase = createClient(URL, ANON_KEY, {
    global: { headers: { Authorization: req.headers.get('Authorization')! } },
  });
  // 用调用者的 JWT 访问数据库(受 RLS 约束)
  const { data } = await supabase.from('profiles').select('*');
  return new Response(JSON.stringify(data), { headers: { 'Content-Type': 'application/json' } });
});
  • Webhook 处理:Stripe 支付回调、GitHub 事件。
  • 绕过 CORS/密钥:在边缘调用第三方 API,密钥不暴露给前端。
  • 聚合查询:多表 JOIN/RPC 在函数里执行,避免前端多次往返。
  • 定时任务(Cron):配 pg_cron 或 Supabase 的 Schedule 定时触发函数。

3. 与 Lambda 的差异

维度Supabase Edge FunctionsAWS Lambda
运行时Deno(TS 原生)Node/Python/Java/...
部署位置全球 CDN 边缘(就近)单区域
冷启动毫秒级百毫秒级(Node)
适合轻量、全球、低延迟重计算、长任务、生态丰富

Edge Functions 不适合长任务(默认超时短,免费层 150s);重计算/大数据处理仍用 Lambda 或单独的后端。

四、定价:免费层无限 API 调用

Supabase 定价的核心吸引力:免费层不限 API 请求次数(与 Firebase 按读写计次不同)。

免费层Pro($25/月)
项目数2 个8 个
API 请求无限无限
数据库500MB8GB
存储1GB100GB
月活用户(MAU)50k100k
Edge Functions 调用500k/月2M/月起
Edge Functions 流量500MB250GB
Realtime 并发连接200500+
PITR(时间点恢复)
  • 免费层风险:项目 7 天无活动会暂停(数据保留,可唤醒);适合个人/原型。
  • 超额计费:Pro 超出额度按量计费(如每 GB 存储、每 MAU)。
  • vs Firebase 计费:Firebase 按 Firestore 读写次数、带宽、函数调用计费,流量大了账单不可控;Supabase 免费层无限 API 调用,对读多场景更友好。

下一步

掌握三大产品后,进入 参考——Supabase vs Firebase 完整对比大表、产品矩阵、易错点清单与权威链接,把整个能力图景收口。