跳轉到主要內容

概述

Supabase 是一種開源 Firebase 替代方案,可為您的 Superun 應用程序提供完整的後端解決方案。它提供 PostgreSQL 數據庫、身份驗證、實時訂閱和存儲 - 所有這些都可以通過簡單的 API 進行訪問。

什麼是 Supabase

Supabase 提供構建全棧應用程序所需的一切:
  • PostgreSQL 數據庫: 強大的開源關係數據庫
  • 身份驗證: 具有多個提供商的內置用戶管理
  • **實時訂閱:**實時監聽數據庫變化
  • 存儲: 文件上傳和管理
  • **邊緣功能:**用於自定義邏輯的無服務器功能
  • 自動生成的 API: 從數據庫架構生成的 REST 和 GraphQL API

主要優點

  • 快速開發: 在幾分鐘內獲得完整的後端並運行
  • 實時功能: 內置實時訂閱以獲取實時更新
  • 可擴展: 基於 PostgreSQL 構建,可從原型擴展到生產
  • 開源: 無供應商鎖定,如果需要可自行託管
  • 開發人員經驗: 優秀的工具和文檔

入門

1. 創建一個 Supabase 項目

  1. 前往 Supabase.com 並註冊
  2. 點擊“新建項目”
  3. 選擇您的組織並輸入項目詳細Info
  4. 選擇離您的用戶較近的區域 5.設置強數據庫密碼 6.點擊“創建新項目”

2. 獲取您的項目憑證

創建項目後,您將需要:
  • 項目 URL: 在設置 → API 中找到
  • 匿名密鑰: 用於客戶端操作的公鑰
  • 服務角色密鑰: 服務器端操作的密鑰(確保安全!)

3. 在 Superun 中配置 Supabase

在您的 Superun 項目中:
  1. 轉到 設置 → 集成
  2. 找到 Supabase 並單擊 連接
  3. 輸入您的項目 URL 和匿名密鑰
  4. 單擊“保存
Superun 將自動配置您的項目以使用 Supabase。

數據庫設置

創建表

您可以通過兩種方式創建表:

使用 Supabase 儀表板

  1. 轉到您的 Supabase 項目儀表板
  2. 導航至 表編輯器
  3. 單擊“新建表
  4. 定義表架構
  5. 設置行級安全性 (RLS) 策略

使用 SQL

-- Create a users table
CREATE TABLE users (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  name TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Create a posts table
CREATE TABLE posts (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  title TEXT NOT NULL,
  content TEXT,
  author_id UUID REFERENCES users(id),
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

行級安全性 (RLS)

啟用 RLS 以保護您的數據:
-- Enable RLS on tables
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;

-- Create policies
CREATE POLICY "Users can view their own data" ON users
  FOR SELECT USING (auth.uid() = id);

CREATE POLICY "Users can update their own data" ON users
  FOR UPDATE USING (auth.uid() = id);

CREATE POLICY "Anyone can view posts" ON posts
  FOR SELECT USING (true);

CREATE POLICY "Users can create posts" ON posts
  FOR INSERT WITH CHECK (auth.uid() = author_id);

驗證

設置身份驗證

  1. 轉到 Supabase 儀表板中的 身份驗證 → 設置
  2. 配置您的網站 URL(您的 Superun 應用程序 URL)
  3. 啟用所需的身份驗證提供程序

可用的提供商

  • 電子郵件/密碼: 傳統電子郵件和密碼身份驗證
  • 魔法鏈接: 通過電子郵件進行無密碼身份驗證
  • OAuth 提供商: Google、GitHub、Twitter、Discord 等。
  • **電話:**短信驗證

在您的應用程序中使用身份驗證

Superun 自動生成認證組件:
// Login component
import { useState } from 'react';
import { Supabase } from './lib/Supabase';

export default function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleLogin = async (e) => {
    e.preventDefault();
    const { data, error } = await Supabase.auth.signInWithPassword({
      email,
      password,
    });
    
    if (error) {
      console.error('Login error:', error);
    } else {
      console.log('Logged in:', data.user);
    }
  };

  return (
    <form onSubmit={handleLogin}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
        required
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password"
        required
      />
      <button type="submit">Login</button>
    </form>
  );
}

用戶管理

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

// Sign up new user
const { data, error } = await Supabase.auth.signUp({
  email: '[email protected]',
  password: 'password123',
});

// Sign out
await Supabase.auth.signOut();

數據庫操作

讀取數據

// Fetch all posts
const { data: posts, error } = await Supabase
  .from('posts')
  .select('*')
  .order('created_at', { ascending: false });

// Fetch posts with author information
const { data: posts, error } = await Supabase
  .from('posts')
  .select(`
    *,
    author:users(name, email)
  `);

// Filter and paginate
const { data: posts, error } = await Supabase
  .from('posts')
  .select('*')
  .eq('author_id', userId)
  .range(0, 9); // First 10 posts

創建數據

// Insert a new post
const { data, error } = await Supabase
  .from('posts')
  .insert([
    {
      title: 'My First Post',
      content: 'This is the content of my post',
      author_id: user.id,
    }
  ]);

更新數據

// Update a post
const { data, error } = await Supabase
  .from('posts')
  .update({ title: 'Updated Title' })
  .eq('id', postId);

刪除數據

// Delete a post
const { error } = await Supabase
  .from('posts')
  .delete()
  .eq('id', postId);

實時訂閱

實時監聽數據庫變化:
import { useEffect, useState } from 'react';
import { Supabase } from './lib/Supabase';

export default function PostsList() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    // Fetch initial data
    fetchPosts();

    // Set up real-time subscription
    const subscription = Supabase
      .channel('posts')
      .on('postgres_changes', 
        { event: '*', schema: 'public', table: 'posts' },
        (payload) => {
          console.log('Change received!', payload);
          // Update local state based on the change
          if (payload.eventType === 'INSERT') {
            setPosts(prev => [payload.new, ...prev]);
          } else if (payload.eventType === 'UPDATE') {
            setPosts(prev => prev.map(post => 
              post.id === payload.new.id ? payload.new : post
            ));
          } else if (payload.eventType === 'DELETE') {
            setPosts(prev => prev.filter(post => post.id !== payload.old.id));
          }
        }
      )
      .subscribe();

    return () => {
      subscription.unsubscribe();
    };
  }, []);

  const fetchPosts = async () => {
    const { data, error } = await Supabase
      .from('posts')
      .select('*')
      .order('created_at', { ascending: false });
    
    if (data) setPosts(data);
  };

  return (
    <div>
      {posts.map(post => (
        <div key={post.id}>
          <h3>{post.title}</h3>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  );
}

文件存儲

上傳文件

// Upload a file
const uploadFile = async (file) => {
  const { data, error } = await Supabase.storage
    .from('avatars')
    .upload(`${user.id}/${file.name}`, file);

  if (error) {
    console.error('Upload error:', error);
  } else {
    console.log('File uploaded:', data);
  }
};

下載文件

// Get public URL for a file
const { data } = Supabase.storage
  .from('avatars')
  .getPublicUrl(`${user.id}/avatar.jpg`);

// Download a file
const { data, error } = await Supabase.storage
  .from('avatars')
  .download(`${user.id}/avatar.jpg`);

邊函數

為自定義邏輯創建無服務器函數:
// functions/send-email/index.ts
import { serve } from "https://deno.land/[email protected]/http/server.ts"

serve(async (req) => {
  const { email, subject, body } = await req.json()
  
  // Send email logic here
  
  return new Response(
    JSON.stringify({ success: true }),
    { headers: { "Content-Type": "application/json" } }
  )
})

最佳實踐

### 安全
  1. 始終在您的桌子上啟用 RLS
  2. 僅在服務器端使用服務角色密鑰
  3. 驗證客戶端和服務器上的數據
  4. 對敏感數據使用環境變量
### 表現
  1. 使用 select() 限制返回Columns
  2. 對大型數據集實現分頁
  3. 對經常查詢的Columns使用索引
  4. 考慮使用視圖進行複雜查詢
### 發展
  1. 使用 TypeScript 獲得更好的類型安全性
  2. 為架構更改創建數據庫遷移
  3. 徹底測試您的 RLS 政策
  4. 使用 Supabase CLI 進行本地開發

常見模式

用戶個人資料

// Create user profile on signup
const createUserProfile = async (user) => {
  const { error } = await Supabase
    .from('profiles')
    .insert({
      id: user.id,
      email: user.email,
      created_at: new Date().toISOString(),
    });
  
  if (error) console.error('Error creating profile:', error);
};

數據關係

// Fetch posts with comments
const { data: posts, error } = await Supabase
  .from('posts')
  .select(`
    *,
    comments (
      id,
      content,
      author:profiles(name)
    )
  `);

搜索功能

// Full-text search
const { data: posts, error } = await Supabase
  .from('posts')
  .select('*')
  .textSearch('title,content', 'search term');

故障排除

常見問題

問:我收到權限被拒絕的錯誤 答:檢查您的 RLS 政策。確保它們允許您嘗試執行的操作。 問:實時訂閱不起作用 答:確保您訂閱了正確的頻道,並且 RLS 策略允許用戶查看數據。 問:文件上傳失敗 答:檢查您的存儲桶策略和文件大小限制。 問:身份驗證不起作用 答:驗證您的網站 URL 是否在 Supabase 儀表板中正確配置。

從其他服務遷移

來自 Firebase

  • Firestore → PostgreSQL: 使用 Supabase 的 JSON 列來獲取類似文檔的數據
  • Firebase Auth → Supabase Auth: 類似的 API,易於遷移
  • Firebase 存儲 → Supabase 存儲: 兼容的 S3 API

來自其他數據庫

  • MySQL → PostgreSQL: 使用 Supabase 的遷移工具
  • MongoDB → PostgreSQL: 將數據重組為關係格式

需要幫助嗎?

查看我們的常見問題解答,了解常見的 Supabase 集成問題和故障排除提示。