🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Supabase Complete Guide 2026: Datenbank-, Authentifizierungs-, Echtzeit- und Edge-Funktionen

⏱️5 min read  ·  916 words

Supabase ist die Open-Source-Firebase-Alternative, die Ihnen eine PostgreSQL-Datenbank, Authentifizierung, Echtzeitabonnements, Edge-Funktionen und Speicher bietet – alles auf einer Plattform. Im Jahr 2026 unterstützt Supabase Startups und Unternehmen gleichermaßen mit seinem entwicklerfreundlichen DX und der leistungsstarken PostgreSQL-Basis. Dieser Leitfaden deckt alles von der Projekteinrichtung bis zur Produktion ab.

Was Supabase bietet

  • PostgreSQL-Datenbank— vollständiges Postgres mit direktem SQL-Zugriff
  • Automatisch generierte REST-API— PostgREST verwandelt Ihre Tabellen in REST-Endpunkte
  • Echtzeit-Abonnements– Tabellenänderungen über WebSocket abhören
  • Authentifizierung– E-Mail, OAuth (Google, GitHub, Apple), Telefon-OTP
  • Lagerung– Datei-Uploads mit CDN und Zugriffsrichtlinien auf Zeilenebene
  • Kantenfunktionen– Deno-basierte serverlose Funktionen am Edge
  • Vektorsuche– pgvector-Erweiterung für KI-Einbettungen

Aufstellen

npm install @supabase/supabase-js

# Or create project at supabase.com (free tier: 500MB DB, 1GB storage)

# Environment variables
SUPABASE_URL=https://xyzcompany.supabase.co
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIs...  # public, safe for frontend
SUPABASE_SERVICE_ROLE_KEY=eyJ...              # private, server only!

Datenbankoperationen

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

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_ANON_KEY!
);

// SELECT
const { data: users, error } = await supabase
  .from('users')
  .select('id, name, email, created_at')
  .eq('active', true)
  .order('created_at', { ascending: false })
  .limit(10);

// SELECT with relations (foreign table)
const { data: posts } = await supabase
  .from('posts')
  .select(`
    id,
    title,
    content,
    users(name, email),
    categories(name)
  `)
  .eq('published', true);

// INSERT
const { data, error } = await supabase
  .from('posts')
  .insert({
    title: 'My Post',
    content: 'Content here',
    author_id: userId,
    published: false,
  })
  .select()
  .single();

// UPDATE
const { data: updated } = await supabase
  .from('posts')
  .update({ published: true })
  .eq('id', postId)
  .select()
  .single();

// DELETE (soft delete via RLS is better)
await supabase.from('posts').delete().eq('id', postId);

// UPSERT
await supabase
  .from('user_settings')
  .upsert({ user_id: userId, theme: 'dark', language: 'en' })
  .onConflict('user_id');

Sicherheit auf Zeilenebene (RLS)

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

-- Users can read all published posts
CREATE POLICY "Anyone can read published posts"
  ON posts FOR SELECT
  USING (published = true);

-- Users can only see their own draft posts
CREATE POLICY "Users see own drafts"
  ON posts FOR SELECT
  USING (author_id = auth.uid() AND published = false);

-- Users can only insert/update their own posts
CREATE POLICY "Users manage own posts"
  ON posts FOR ALL
  USING (author_id = auth.uid());

-- Admin bypass (service role key bypasses RLS)
-- Use service role key in server-side code for admin operations

Authentifizierung

// Sign up
const { data, error } = await supabase.auth.signUp({
  email: 'alice@example.com',
  password: 'securepassword',
  options: {
    data: { full_name: 'Alice Chen' }  // stored in user metadata
  }
});

// Sign in
const { data: session } = await supabase.auth.signInWithPassword({
  email: 'alice@example.com',
  password: 'securepassword'
});

// OAuth (Google, GitHub, etc.)
await supabase.auth.signInWithOAuth({
  provider: 'github',
  options: {
    redirectTo: `${window.location.origin}/auth/callback`
  }
});

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

// Listen to auth state changes
supabase.auth.onAuthStateChange((event, session) => {
  if (event === 'SIGNED_IN') setUser(session?.user ?? null);
  if (event === 'SIGNED_OUT') setUser(null);
});

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

// Server-side auth (Next.js)
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';

export function createServerSupabase() {
  const cookieStore = cookies();
  return createServerClient(
    process.env.SUPABASE_URL!,
    process.env.SUPABASE_ANON_KEY!,
    { cookies: { get: (name) => cookieStore.get(name)?.value } }
  );
}

Echtzeit-Abonnements

// Subscribe to table changes
const subscription = supabase
  .channel('posts-changes')
  .on(
    'postgres_changes',
    { event: '*', schema: 'public', table: 'posts' },
    (payload) => {
      console.log('Change received:', payload.eventType, payload.new);
      if (payload.eventType === 'INSERT') addPost(payload.new);
      if (payload.eventType === 'UPDATE') updatePost(payload.new);
      if (payload.eventType === 'DELETE') removePost(payload.old);
    }
  )
  .subscribe();

// Cleanup
subscription.unsubscribe();

// Broadcast (custom events between clients)
const channel = supabase.channel('room-1');
channel
  .on('broadcast', { event: 'cursor-pos' }, ({ payload }) => {
    updateCursor(payload.userId, payload.x, payload.y);
  })
  .subscribe();

// Send broadcast
await channel.send({
  type: 'broadcast',
  event: 'cursor-pos',
  payload: { userId, x: mouseX, y: mouseY }
});

Kantenfunktionen

// supabase/functions/send-email/index.ts
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

serve(async (req: Request) => {
  const { userId, subject, body } = await req.json();

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

  const { data: user } = await supabase
    .from('users')
    .select('email')
    .eq('id', userId)
    .single();

  // Send email via Resend
  await fetch('https://api.resend.com/emails', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${Deno.env.get('RESEND_API_KEY')}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      from: 'app@myapp.com',
      to: user.email,
      subject,
      html: body,
    }),
  });

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

Vektorsuche (KI/Semantik)

-- Enable pgvector
CREATE EXTENSION IF NOT EXISTS vector;

-- Add embedding column
ALTER TABLE articles ADD COLUMN embedding vector(384);

-- Create vector index
CREATE INDEX ON articles USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);

-- Semantic search function
CREATE OR REPLACE FUNCTION semantic_search(query_embedding vector(384), match_count int = 10)
RETURNS TABLE(id bigint, title text, similarity float)
LANGUAGE plpgsql AS $$
BEGIN
  RETURN QUERY
  SELECT
    articles.id,
    articles.title,
    1 - (articles.embedding <=> query_embedding) AS similarity
  FROM articles
  WHERE articles.embedding IS NOT NULL
  ORDER BY articles.embedding <=> query_embedding
  LIMIT match_count;
END;
$$;

// Call semantic search
const { data: results } = await supabase.rpc('semantic_search', {
  query_embedding: await generateEmbedding(searchQuery),
  match_count: 10
});

Supabase im Jahr 2026 ist der schnellste Weg, ein Produktions-Backend aufzubauen. Sie erhalten PostgreSQL-Leistung, Echtzeitabonnements, Authentifizierung und Edge-Funktionen mit einer Entwicklererfahrung, die besser ist als bei Firebase – und die Daten gehören tatsächlich Ihnen. Beginnen Sie mit der kostenlosen Stufe (unbegrenzte API-Aufrufe, 500 MB Datenbank) und migrieren Sie zu Pro (25 $/Monat), wenn Sie mehr Ressourcen benötigen.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা