跳到主要内容

Cursor Supabase:AI 驱动的后端即服务开发

Cursor Supabase

Supabase 为现代应用提供了强大的开源 Firebase 替代方案。与 Cursor 的 AI 能力结合使用,您可以快速搭建认证、数据库、实时订阅和 serverless functions。本指南涵盖使用 Cursor 的 Supabase 工作流。

前置条件​

在开始之前:

  • Cursor 已安装(建议使用最新版本)
  • Supabase 账户(免费层即可)
  • Supabase CLI 已安装用于本地开发

项目设置​

初始化 Supabase​

# 安装 Supabase CLI
npm install -g supabase

# 登录
supabase login

# 初始化项目
supabase init

# 链接到您的项目
supabase link --project-ref your-project-ref

安装客户端​

npm install @supabase/supabase-js
npm install -D @supabase/cli

环境变量​

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

数据库模式设计​

使用 AI 设计表​

为博客应用设计 Supabase 表:
- 文章(含类别、作者关系)
- 评论(嵌套回复)
- 用户资料(扩展 auth.users)

Cursor 生成 SQL:

-- 启用 RLS
alter table auth.users enable row level security;

-- 用户资料表
CREATE TABLE profiles (
id uuid references auth.users on delete cascade primary key,
username text unique not null,
avatar_url text,
created_at timestamptz default now()
);

-- 文章表
CREATE TABLE posts (
id bigint generated always as identity primary key,
title text not null,
slug text unique not null,
content text not null,
status text default 'draft',
author_id uuid references profiles(id) not null,
created_at timestamptz default now(),
updated_at timestamptz default now()
);

-- 评论表
CREATE TABLE comments (
id bigint generated always as identity primary key,
post_id bigint references posts(id) on delete cascade,
parent_id bigint references comments(id) on delete cascade,
author_id uuid references profiles(id),
content text not null,
created_at timestamptz default now()
);

认证集成​

Next.js 认证​

// lib/supabase.ts
import { createClient } from '@supabase/supabase-js';

export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);

// middleware.ts
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs';

export async function middleware(req: NextRequest) {
const res = NextResponse.next();
const supabase = createMiddlewareClient({ req, res });
const { data: { session } } = await supabase.auth.getSession();
return res;
}

受保护路由​

// app/dashboard/page.tsx
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';

export default async function Dashboard() {
const supabase = createServerComponentClient({ cookies });
const { data: { session } } = await supabase.auth.getSession();

if (!session) {
redirect('/login');
}

return <div>Welcome {session.user.email}</div>;
}

行级安全 (RLS)​

策略生成​

-- 用户只能查看自己的资料
CREATE POLICY "Users can view own profile"
ON profiles FOR SELECT
USING (auth.uid() = id);

-- 用户只能更新自己的资料
CREATE POLICY "Users can update own profile"
ON profiles FOR UPDATE
USING (auth.uid() = id);

-- 公开文章所有人可见
CREATE POLICY "Published posts are viewable"
ON posts FOR SELECT
USING (status = 'published');

实时订阅​

客户端订阅​

'use client';

import { useEffect, useState } from 'react';
import { supabase } from '@/lib/supabase';

export function RealtimeComments({ postId }: { postId: string }) {
const [comments, setComments] = useState([]);

useEffect(() => {
const channel = supabase
.channel('comments')
.on(
'postgres_changes',
{
event: '*',
schema: 'public',
table: 'comments',
filter: `post_id=eq.${postId}`,
},
(payload) => {
setComments((prev) => [...prev, payload.new]);
}
)
.subscribe();

return () => {
supabase.removeChannel(channel);
};
}, [postId]);

return (
<div>
{comments.map((comment) => (
<div key={comment.id}>{comment.content}</div>
))}
</div>
);
}

Edge Functions​

创建 Function​

// supabase/functions/process-payment/index.ts
import { serve } from 'https://deno.land/[email protected]/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

serve(async (req) => {
const { amount, currency } = await req.json();

const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
);

// 处理支付逻辑
const result = await processPayment({ amount, currency });

return new Response(JSON.stringify(result), {
headers: { 'Content-Type': 'application/json' },
});
});

部署​

supabase functions deploy process-payment

快速参考​

操作命令/代码
启动本地环境supabase start
数据库迁移supabase db diff
生成类型supabase gen types
部署 functionssupabase functions deploy
查看日志supabase functions logs

相关资源​

最后更新:2025 年 7 月