Native Google- und Apple-Sign-in in einer React App implementieren, unterstützt durch Supabase Auth, und kapselt dieselbe UI in Capacitor ohne Probleme mit Mobile-Browser-Redirects. Capgo Social Login (@capgo/capacitor-social-login) übernimmt die nativen Provider-Sheets; du tauschst den Provider-ID-Token gegen eine Supabase-Session mit signInWithIdToken.
Dieser Artikel erweitert unseren bestehenden Supabase + Social Login Guide um ein vollständiges React + Vite Walkthrough (Projektstruktur, Provider, Routes, Capacitor Wiring). Für Provider-Dashboards und Platform-Keys nutze weiterhin die Supabase Integration Docs und Google + Supabase Setup. Ähnliche Beiträge: Google Sign-in mit Capacitor, Apple Sign-in mit Capacitor, und Authentifizierungsoptionen in Capacitor.
Inhaltsverzeichnis
- Das wirst du bauen
- Gesamter Authentifizierungs-Flow
- Basis React (Vite) Anwendung
- Supabase Projekt und Google Provider
- Provider in Supabase konfigurieren
- Social Login Plugin initialisieren
- Supabase Client und React Auth-Layer
- Login-UI und geschützte Routen
- Capacitor zur React-App hinzufügen
- Plattform-Konfiguration
- Datenbankzugriff mit RLS
- Bekannte Probleme und Troubleshooting
- Sicherheitshinweise
Das wirst du bauen
- Ein Vite + React + TypeScript Web-App mit Login-Buttons und einer Debug-Ansicht für angemeldete Nutzer
- Supabase Auth Sessions aus Native erstellt Google (und optional Apple) ID-Tokens
- Derselbe Bundle, der läuft in Capacitor auf iOS und Android
- Ein nonce-sicherer Google-Flow passend zum Plugin-Beispiel-App
Gesamter Authentifizierungs-Flow
Mit @capgo/capacitor-social-login, führt die Mobile App aus es nicht verlassen auf signInWithOAuth Redirects innerhalb der WebView. Das native SDK liefert einen ID-Token; Supabase validiert diesen und stellt ein eigenes JWT aus.

An Web, kannst du weiterhin dasselbe Plugin nutzen (siehe Google Web-Setup). Behandle alle OAuth-Return-URLs in deinem Router, falls du später einen Browser-Fallback hinzufügst.
Basis React (Vite) Anwendung
Erstelle eine neue App (oder nutze eine bestehende React-Codebase):
bun create vite capgo-supabase-auth --template react-ts
cd capgo-supabase-auth
bun install
bun add @supabase/supabase-js @capgo/capacitor-social-login react-router-dom @capacitor/core
Starte den Dev-Server:
bun run dev

Ziel-Ordnerstruktur:

Umgebungsvariablen eintragen in .env.local (Secrets niemals committen):
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-public-key
VITE_GOOGLE_WEB_CLIENT_ID=your-web-client-id.apps.googleusercontent.com
VITE_GOOGLE_IOS_CLIENT_ID=your-ios-client-id.apps.googleusercontent.com
VITE_APPLE_SERVICE_ID=com.yourapp.signin
VITE_SUPABASE_APPLE_CALLBACK_URL=https://your-project-ref.supabase.co/functions/v1/apple-signin-callback
Warum Supabase mit Social Login nutzen?
Supabase bietet ein robustes Backend-as-a-Service mit integrierter Authentifizierung, während das @capgo/capacitor-social-login Plugin native Social Authentication für iOS, Android und Web bietet. Für eine engere Supabase-Integration, @capgo/capacitor-supabase bietet native Auth-Helper und JWT-Zugriff. Zusammen ermöglichen sie:
- Nahtlose Social Authentication
- Sicheres Token-Management
- Cross-Platform-Kompatibilität
- Echtzeit-Datenbank-Integration
- Integriertes User-Management
Voraussetzungen
Before starting, ensure you have:
- Ein aufgesetztes Capacitor Projekt
- Ein Supabase-Konto und ein Projekt
- Developer-Accounts für deine gewählten Social Provider (Google, Apple, Facebook)
Schritt 1: Social Login Plugin installieren und konfigurieren
Installiere zuerst das Capgo Social Login Plugin:
bun add @capgo/capacitor-social-login
Ausführen bunx cap sync danach du fügst Capacitor und native Plattformen in Füge Capacitor der React-App hinzu. Die untenstehende Vite-Anleitung funktioniert vor diesem Schritt im Browser.
Siehe den Social Login und Supabase Plugin-Seiten für die plattformspezifische Einrichtung.
Schritt 2: Supabase-Projekt einrichten

Erstelle und konfiguriere dein Supabase-Projekt
-
Erstelle ein Supabase-Projekt:
- Gehe zu supabase.com und registriere dich bzw. melde dich an
- Klicken „New Project“
- Wähle deine Organisation
- Gib einen Projektnamen ein (z. B. „MyApp Auth“)
- Lege einen Datenbank-Passwort (sicher aufbewahren)
- Wähle deine Region (die nächstgelegene zu deinen Usern wählen)
- Klicken „Neues Projekt erstellen“
-
Projekt-Credentials abrufen:
- Nach dem Erstellen gehe zu Einstellungen > API
- Kopiere deine Projekt-URL (z. B.
https://your-project-ref.supabase.co) - Kopiere deine anon public API Key
- Save these for later use in your app
Authentication-Einstellungen konfigurieren
-
Allgemeine Authentication-Einstellungen einrichten:
- Gehe zu Authentifizierung > Einstellungen
- Unter Allgemeine Einstellungen:
- Setzen Sie Website-URL zur URL deiner App (z. B.
https://yourdomain.comoderhttp://localhost:3000für die Entwicklung) - Zusätzlich hinzufügen, Redirect-URLs falls nötig:
http://localhost:3000 https://yourdomain.com capacitor://localhost (for mobile apps)
- Setzen Sie Website-URL zur URL deiner App (z. B.
-
E-Mail-Einstellungen konfigurieren (optional, aber empfohlen):
- Unter SMTP-Einstellungen, konfiguriere deinen E-Mail-Anbieter
- Dies ermöglicht E-Mail-Bestätigungen und Passwort-Resets
- Für die Entwicklung kannst du den integrierten E-Mail-Service nutzen
Social Authentication Provider aktivieren
- Navigiere zum Bereich Providers:
- Gehe zu Authentifizierung > Provider in deinem Supabase Dashboard
- Du siehst eine Liste der verfügbaren Social Provider
- Jeder Provider hat einen Aktivieren Toggle- und Konfigurationsoptionen
Konfigurieren wir nun die einzelnen Social Provider im Detail:
Schritt 3: Social Provider in Supabase konfigurieren
Google Authentication in Supabase einrichten
Besorge zuerst deine Google OAuth-Credentials:
Folge unserer ausführlichen Google-Setup-Anleitung: Google Authentication Setup
Diese Anleitung umfasst:
- Erstellen eines Google Cloud Projekts
- Einrichten von OAuth 2.0 Credentials für Web, iOS und Android
- Konfigurieren des Consent Screens
- Abrufen der benötigten Client IDs und Secrets
Nach dem Google-Setup erfolgt die Konfiguration in Supabase:
Folge dem Supabase + Google Leitfaden für Screenshots der Dashboards hier klicken.
- Google Provider in Supabase aktivieren:
- Gehe in deinem Supabase Dashboard zu Authentifizierung > Provider
- Finde Google und aktiviere ihn AN
- Füge den Web, iOS, und Android Client-IDs aus der Google Cloud (Plattformen, die du nicht nutzt, überspringen)
- Klicken Speichern
Wichtig für dieses React-Tutorial: when you use signInWithIdToken mit @capgo/capacitor-social-login, machst du es nicht OAuth-Daten benötigen Client Secret oder die Callback-URL-Felder für Google. Registriere alle Client-IDs, die Supabase bei der Validierung der Token von jeder Plattform akzeptiert.
Apple Authentication in Supabase einrichten
Apple-Zugangsdaten abrufen:
Folge unserer detaillierten Apple-Setup-Anleitung: Apple Authentication Setup
Diese Anleitung umfasst:
- Einrichtung deines Apple Developer Accounts
- Erstellen von App IDs und Service IDs
- Konfigurieren der Sign in with Apple Capability
- Generieren der erforderlichen Private Keys
- Plattformspezifisches Setup für iOS, Android und Web
Nach dem Apple-Setup in Supabase konfigurieren:
- Apple Provider in Supabase aktivieren:
- Gehe zu Authentication > Providers und umschalten Apple AN
- Konfiguration ausfüllen:
- Client-ID: Deine iOS App ID und Apple Service ID (bei Multi-Plattform-Support), durch Komma getrennt (z. B.
com.yourapp,com.yourapp.signin). iOS-Tokens nutzen die App ID Audience; Android und Web nutzen die Service ID. Siehe Supabase Apple Allgemeines. - Für den Ablauf
signInWithIdTokendieses Tutorials@capgo/capacitor-social-loginmusst du es nicht ein OAuth Client Secret oder eine Supabase OAuth Callback URL im Apple Provider Formular angeben.
- Client-ID: Deine iOS App ID und Apple Service ID (bei Multi-Plattform-Support), durch Komma getrennt (z. B.
- Klicken Speichern
Hinweis: Das Apple Authentication Setup ist aufgrund der Anforderungen an Service IDs, Private Keys und plattformspezifische Redirect URLs am komplexesten. Folge unserer Dokumentation für jede Plattform genau.
Facebook Authentication in Supabase einrichten
Facebook-Credentials abrufen:
Folge unserer Anleitung zum Facebook-Setup: Facebook Authentication Setup
Diese Anleitung umfasst:
- Erstellen eines Facebook Developer Accounts und einer App
- Hinzufügen des Facebook Login Produkts
- Konfigurieren der OAuth Redirect URIs
- Abrufen von App ID, App Secret und Client Token
- Plattformspezifische Konfiguration für iOS und Android
Nach dem Facebook-Setup erfolgt die Konfiguration in Supabase:
- Facebook Provider in Supabase aktivieren:
- Gehe zu Authentifizierung > Provider und umschalten Facebook AN
- Konfiguration ausfüllen:
- Client-ID: Deine Facebook App ID
- Client Secret: Dein Facebook App Secret
- Redirect-URL:
https://your-project-ref.supabase.co/auth/v1/callback(auto-filled)
- Klicken „Speichern“
Wichtig: Stelle sicher, dass du die Supabase Callback-URL (https://your-project-ref.supabase.co/auth/v1/callback) in deiner Facebook-App zu den Gültige OAuth-Redirect-URIs in den Facebook Login-Einstellungen hinzufügst.
Wichtige Hinweise zur Supabase-Konfiguration
Row Level Security (RLS):
- Nach der Einrichtung der Authentifizierung aktiviere RLS für deine Tabellen unter
- Gehe zu Datenbank > Tabellen und umschalten RLS aktivieren für jede Tabelle
- Erstelle Policies, um den Datenzugriff basierend auf authentifizierten Usern zu steuern
Benutzerverwaltung:
- Authentifizierte User anzeigen unter Authentifizierung > Benutzer
- Auth-Events überwachen unter Authentifizierung > Logs
- Email-Templates einrichten unter Authentifizierung > E-Mail-Vorlagen
Konfiguration testen:
- Nutze das integrierte Auth-Testtool von Supabase
- Gehe zu Authentifizierung > Nutzer und klicke auf „Nutzer einladen“ um E-Mail-Flows zu testen
- Schau in die Logs Abschnitt für Authentifizierungsfehler
Schritt 4: Social Login Plugin konfigurieren
Nachdem Supabase konfiguriert ist, musst du das Social Login Plugin mit den entsprechenden Credentials einrichten. Wichtig: Das Plugin benötigt die OAuth-Credentials von den ursprünglichen Providern (nicht von Supabase), während Supabase die serverseitige Authentifizierung übernimmt.
So funktioniert der Authentication Flow
Bevor du mit der Konfiguration startest, hier der Ablauf:
- Plugin authentifiziert nativ beim Social Provider (Google/Apple/Facebook)
- Plugin erhält Tokens (Access Token, ID Token) vom Provider
- Deine App sendet diese Tokens an Supabase mit
signInWithIdToken() - Supabase validiert die Tokens beim Provider und erstellt eine User Session
- Supabase gibt zurück einen eigenen JWT-Token für die authentifizierten Requests deiner App
Google Plugin Konfiguration
Das Plugin benötigt deine Web-Client-ID für alle Plattformen und optional eine iOS Client-ID für iOS-spezifische Features:
import { SocialLogin } from '@capgo/capacitor-social-login';
await SocialLogin.initialize({
google: {
// Use the same Web Client ID you configured in Supabase
webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
// Optional: iOS Client ID for iOS-specific features
iOSClientId: 'YOUR_IOS_CLIENT_ID.apps.googleusercontent.com',
// Use online mode so the plugin returns an idToken for Supabase
mode: 'online'
}
});
Wichtige Punkte für Google:
- Nutze das Web-Client-ID (keine Android/iOS Client IDs) für das
webClientIdFeld - Das Plugin funktioniert auf allen Plattformen nur mit der Web Client ID
- Der
iOSClientIdist optional und wird nur für iOS-spezifische Google-Features genutzt
Apple Plugin Konfiguration
Die Apple-Konfiguration unterscheidet sich zwischen iOS und Android:
Für iOS (natives Apple Sign-In):
await SocialLogin.initialize({
apple: {
// No additional configuration needed for iOS
// The plugin uses the native Apple Sign-In capability
}
});
Für Android/Web (erfordert Service ID). Nutze dieselben Redirect-Regeln wie buildApplePluginConfig() im React-Tutorial:
import { Capacitor } from '@capacitor/core';
const platform = Capacitor.getPlatform();
await SocialLogin.initialize({
apple:
platform === 'android'
? {
clientId: 'YOUR_SERVICE_ID',
redirectUrl:
'https://your-project-ref.supabase.co/functions/v1/apple-signin-callback',
}
: {
clientId: 'YOUR_SERVICE_ID',
redirectUrl: window.location.href,
},
});
Wichtige Punkte für Apple:
- iOS nutzt natives Sign in with Apple (keine extra Config nötig)
- Android nutzt deine Service ID und die Supabase
apple-signin-callbackEdge Function URL - Web nutzt deine Service ID und
window.location.href, die mit den Apple Return URLs übereinstimmen muss
Facebook Plugin Konfiguration
Facebook benötigt deine App ID und den Client Token:
await SocialLogin.initialize({
facebook: {
appId: 'YOUR_FACEBOOK_APP_ID', // From Facebook Developer Dashboard
clientToken: 'YOUR_FACEBOOK_CLIENT_TOKEN', // From Facebook Developer Dashboard
// Optional: Use Facebook Limited Login (for enhanced privacy)
limitedLogin: false // See our Facebook setup guide for important Limited Login details
}
});
Wichtige Punkte für Facebook:
- Nutze dieselbe App ID, die du in Supabase konfiguriert hast
- Den Client Token findest du in den Basic Settings deiner Facebook App
limitedLogin: trueaktiviert Facebooks datenschutzorientiertes Limited Login Feature (nur iOS)- Wichtig: Siehe unsere Facebook Setup-Guide für Details zum Limited Login, inkl. ATT-Aspekten

Plugin-Initialisierung abschließen
So initialisierst du alle Provider gleichzeitig:
import { SocialLogin } from '@capgo/capacitor-social-login';
export async function initializeSocialLogin() {
await SocialLogin.initialize({
google: {
webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
mode: 'online'
},
facebook: {
appId: 'YOUR_FACEBOOK_APP_ID',
clientToken: 'YOUR_FACEBOOK_CLIENT_TOKEN',
},
apple: {
// Prefer buildApplePluginConfig() from the React walkthrough.
// Android: redirectUrl = Supabase apple-signin-callback Edge Function
// Web: redirectUrl = window.location.href
}
});
}
Wichtige Hinweise:
- Rufe
initialize()einmal beim App-Start, nicht vor jedem Login - Du musst nur die Provider konfigurieren, die du nutzen willst
- Die Credentials stammen von den originalen Providern, nicht von Supabase
- Stelle sicher, dass die Provider-Credentials mit deiner Supabase-Konfiguration übereinstimmen
React Supabase Client und Auth-Layer
Installiere den Supabase Client, falls noch nicht geschehen:
bun add @supabase/supabase-js
Erstelle einen einzelnen Client für den gesamten React-Tree:
// src/lib/supabaseClient.ts
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: false,
},
});
Nonce-Helper für Google + Supabase
Supabase erwartet einen rohen Nonce in signInWithIdToken und einen SHA-256 Digest an Google übergeben. Der Supabase Google Guide dokumentiert den gesamten Flow. Minimale Helfer:
// src/auth/nonce.ts
export function getUrlSafeNonce(): string {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');
}
export async function sha256Hex(message: string): Promise<string> {
const data = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
return Array.from(new Uint8Array(hashBuffer), (b) => b.toString(16).padStart(2, '0')).join('');
}
export async function createGoogleNoncePair(): Promise<{ rawNonce: string; nonceDigest: string }> {
const rawNonce = getUrlSafeNonce();
const nonceDigest = await sha256Hex(rawNonce);
return { rawNonce, nonceDigest };
}
Social Login + Supabase in einem Modul verbinden (Pattern aus dem Beispiel) supabaseAuthUtils.ts):
// src/auth/socialLogin.ts
import { Capacitor } from '@capacitor/core';
import { SocialLogin } from '@capgo/capacitor-social-login';
import { supabase } from '../lib/supabaseClient';
import { createGoogleNoncePair } from './nonce';
export function isAppleLoginConfigured(): boolean {
const platform = Capacitor.getPlatform();
if (platform === 'ios') return true;
const serviceId = import.meta.env.VITE_APPLE_SERVICE_ID;
if (!serviceId) return false;
if (platform === 'android') {
return Boolean(import.meta.env.VITE_SUPABASE_APPLE_CALLBACK_URL);
}
if (platform === 'web') return true;
return false;
}
function buildApplePluginConfig() {
const platform = Capacitor.getPlatform();
if (platform === 'ios') {
return {};
}
if (platform === 'android') {
return {
clientId: import.meta.env.VITE_APPLE_SERVICE_ID,
redirectUrl: import.meta.env.VITE_SUPABASE_APPLE_CALLBACK_URL,
};
}
if (platform === 'web') {
return {
clientId: import.meta.env.VITE_APPLE_SERVICE_ID,
redirectUrl: window.location.href,
};
}
return {};
}
function isGoogleNonceMismatch(error: { message?: string }): boolean {
return (error.message ?? '').toLowerCase().includes('nonce');
}
let initialization: Promise<void> | null = null;
export function ensureSocialLoginInitialized(): Promise<void> {
if (!initialization) {
const initOptions: Parameters<typeof SocialLogin.initialize>[0] = {
google: {
webClientId: import.meta.env.VITE_GOOGLE_WEB_CLIENT_ID,
iOSClientId: import.meta.env.VITE_GOOGLE_IOS_CLIENT_ID,
mode: 'online',
},
};
if (isAppleLoginConfigured()) {
initOptions.apple = buildApplePluginConfig();
}
initialization = SocialLogin.initialize(initOptions).catch((error) => {
initialization = null;
throw error;
});
}
return initialization;
}
async function signInWithGoogleSupabaseOnce(allowNonceRetry: boolean) {
await ensureSocialLoginInitialized();
const { rawNonce, nonceDigest } = await createGoogleNoncePair();
const result = await SocialLogin.login({
provider: 'google',
options: {
scopes: ['email', 'profile'],
nonce: nonceDigest,
},
});
const googleResult = result.result;
if (!googleResult || googleResult.responseType !== 'online' || !googleResult.idToken) {
throw new Error('Google login did not return an ID token');
}
const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'google',
token: googleResult.idToken,
nonce: rawNonce,
});
if (error) {
if (allowNonceRetry && isGoogleNonceMismatch(error)) {
await SocialLogin.logout({ provider: 'google' });
return signInWithGoogleSupabaseOnce(false);
}
throw error;
}
return data;
}
export async function signInWithGoogleSupabase() {
return signInWithGoogleSupabaseOnce(true);
}
export async function signInWithAppleSupabase() {
if (!isAppleLoginConfigured()) {
throw new Error('Apple sign-in is not configured for this platform');
}
await ensureSocialLoginInitialized();
const result = await SocialLogin.login({
provider: 'apple',
options: { scopes: ['email', 'name'] },
});
const appleIdToken = result.result?.idToken;
if (!appleIdToken) throw new Error('Apple login did not return an idToken');
const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'apple',
token: appleIdToken,
});
if (error) throw error;
return data;
}
export async function signOutEverywhere() {
await supabase.auth.signOut();
await Promise.all([
SocialLogin.logout({ provider: 'google' }),
SocialLogin.logout({ provider: 'apple' }),
]);
}
Apple initialize pro Plattform (siehe Supabase Apple Allgemein, Android, Web):
- iOS:
buildApplePluginConfig()gibt zurück{}. Native Sign in with Apple nutzt deine Bundle ID. KeineredirectUrl. - Android:
clientIdist deine Apple Service ID.redirectUrlist deine Supabase Edge Function (apple-signin-callback). Deploy die Function, setze die Apple Return URL auf diesen Endpoint und füge den App Deep Link Intent Filter hinzu, damit der Flow zur WebView zurückkehren kann (Android Supabase Apple Guide). - Web:
clientIdist deine Service ID.redirectUrlistwindow.location.href, die mit einer Return URL im Apple Developer Portal übereinstimmen muss (Web Supabase Apple Guide).
ensureSocialLoginInitialized() fügt den apple Provider nur, wenn isAppleLoginConfigured() wahr ist; so übergibt ein reines Google-Setup keine leeren Android- oder Apple-Web-Credentials.
Das Plugin gibt result.idToken auf allen Plattformen zurück (AppleProviderResponse in @capgo/capacitor-social-login). Registriere sowohl die iOS App ID als auch die Service ID in Supabase, wenn du mehrere Plattformen veröffentlichst.
Session-Status für Komponenten bereitstellen:
// src/auth/useAuth.tsx
import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useState,
type ReactNode,
} from 'react';
import type { Session } from '@supabase/supabase-js';
import { supabase } from '../lib/supabaseClient';
import { ensureSocialLoginInitialized } from './socialLogin';
type AuthContextValue = {
session: Session | null;
loading: boolean;
initError: string | null;
clearInitError: () => void;
};
const AuthContext = createContext<AuthContextValue | null>(null);
export function AuthProvider({ children }: { children: ReactNode }) {
const [session, setSession] = useState<Session | null>(null);
const [loading, setLoading] = useState(true);
const [initError, setInitError] = useState<string | null>(null);
useEffect(() => {
void ensureSocialLoginInitialized()
.then(() => setInitError(null))
.catch((error) => {
setInitError(error instanceof Error ? error.message : 'Social login failed to initialize');
});
supabase.auth.getSession().then(({ data }) => {
setSession(data.session);
setLoading(false);
});
const { data: subscription } = supabase.auth.onAuthStateChange((_event, nextSession) => {
setSession(nextSession);
});
return () => subscription.subscription.unsubscribe();
}, []);
const clearInitError = useCallback(() => setInitError(null), []);
const value = useMemo(
() => ({ session, loading, initError, clearInitError }),
[session, loading, initError, clearInitError],
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}
export function useAuth() {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error('useAuth must be used inside AuthProvider');
return ctx;
}
React-Login-UI und geschützte Routen

Login-Panel:
// src/components/LoginPanel.tsx
import { useState } from 'react';
import {
isAppleLoginConfigured,
signInWithAppleSupabase,
signInWithGoogleSupabase,
} from '../auth/socialLogin';
import { useAuth } from '../auth/useAuth';
export function LoginPanel() {
const { initError, clearInitError } = useAuth();
const [error, setError] = useState<string | null>(null);
const [busy, setBusy] = useState(false);
const showApple = isAppleLoginConfigured();
const run = async (action: () => Promise<unknown>) => {
setBusy(true);
setError(null);
try {
await action();
clearInitError();
} catch (e) {
setError(e instanceof Error ? e.message : 'Sign-in failed');
} finally {
setBusy(false);
}
};
return (
<div>
<button type="button" disabled={busy} onClick={() => run(signInWithGoogleSupabase)}>
Continue with Google
</button>
{showApple ? (
<button type="button" disabled={busy} onClick={() => run(signInWithAppleSupabase)}>
Continue with Apple
</button>
) : null}
{initError ? <p role="alert">{initError}</p> : null}
{error ? <p role="alert">{error}</p> : null}
</div>
);
}
Session-Debug-View (später durch dein echtes Account-UI ersetzen):
// src/components/SessionDebug.tsx
import { useEffect, useState } from 'react';
import type { User } from '@supabase/supabase-js';
import { supabase } from '../lib/supabaseClient';
import { signOutEverywhere } from '../auth/socialLogin';
export function SessionDebug() {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
supabase.auth.getUser().then(({ data }) => setUser(data.user));
}, []);
return (
<div>
<button type="button" onClick={() => signOutEverywhere()}>Sign out</button>
<pre>{JSON.stringify(user, null, 2)}</pre>
</div>
);
}

Routes mit react-router-dom:
// src/App.tsx
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
import { AuthProvider, useAuth } from './auth/useAuth';
import { LoginPanel } from './components/LoginPanel';
import { SessionDebug } from './components/SessionDebug';
function HomePage() {
const { session, loading } = useAuth();
if (loading) return <p>Loading…</p>;
if (session) return <Navigate to="/account" replace />;
return <LoginPanel />;
}
function AccountPage() {
const { session, loading } = useAuth();
if (loading) return <p>Loading…</p>;
if (!session) return <Navigate to="/" replace />;
return <SessionDebug />;
}
export default function App() {
return (
<AuthProvider>
<BrowserRouter>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/account" element={<AccountPage />} />
</Routes>
</BrowserRouter>
</AuthProvider>
);
}
Mount the app in main.tsx wie gewohnt. Nach dem erfolgreichen Login beim Provider onAuthStateChange Updates session und React Router leitet den User zu /account.
Optional: Facebook
Facebook folgt demselben signInWithIdToken Pattern mit dem Access Token aus dem Plugin. Siehe Facebook Setup und dem Provider-Block in Schritt 4.
Füge Capacitor der React-App hinzu
Web-Bundle erstellen und dann native Projekte hinzufügen:
bun run build
bun add @capacitor/core @capacitor/cli @capacitor/ios @capacitor/android
bunx cap init "Capgo Auth Demo" com.example.authdemo --web-dir dist
bunx cap add ios
bunx cap add android

Nach jedem Web-Build synchronisieren:
bun run build
bunx cap sync
Öffne die native IDE, wenn du bereit bist, auf Geräten zu testen:
bunx cap open ios
bunx cap open android
Schließe die Schritte für Google und Apple ab, bevor du auf Hardware testest:
Deep Links und Universal Links
Tutorials, die innerhalb supabase.auth.signInWithOAuth eines WebViews aufgerufen werden, benötigen oft Universal Links oder App-Links damit das OS nach dem Google-Redirect die Kontrolle an die App zurückgibt. Native Google Sign-in mit einem ID-Token verhindert diesen Redirect-Loop, da das Plugin keinen Browser-OAuth-Roundtrip öffnet. Apple auf Android funktioniert anders: Es nutzt weiterhin den Edge Function Redirect und einen App- Deep Link Intent Filter, damit die WebView nach dem Apple-Login fortfahren kann.
Du kannst Deep Links weiterhin für andere Features konfigurieren (Passwort-Reset-Mails, Magic Links, Marketing-URLs). Füge dieselben Pfade zu Authentifizierung > URL-Konfiguration in Supabase und für deine apple-app-site-association / Android Intent-Filter, wenn du diese Flows hinzufügst.
Schritt 8: Plattformspezifische Konfiguration
iOS-Konfiguration
Detaillierte iOS-Setup-Anleitungen findest du in unseren plattformspezifischen Guides:
- Google iOS Setup - URL-Schemes, Info.plist-Konfiguration
- Apple iOS Setup - Sign in with Apple Capability Setup
- Facebook iOS Setup (allgemeiner Facebook-Guide) - Facebook SDK Konfiguration
Kurzzusammenfassung - Hinzufügen zu ios/App/App/Info.plist:
<!-- Google Sign-In URL scheme -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR_REVERSED_CLIENT_ID</string>
</array>
</dict>
</array>
<!-- Apple Sign-In capability -->
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
Folge den verlinkten Guides für die vollständige iOS-Einrichtung inklusive Xcode-Projektkonfiguration.
Android-Konfiguration
Detaillierte Anleitungen zur Android-Einrichtung findest du in unseren plattformspezifischen Guides:
- Google Android Setup - SHA-1 Fingerprints, Google Play Services Konfiguration
- Setup für Apple und Android - Service ID Konfiguration für Android
- Facebook Android Setup (im allgemeinen Facebook Guide) - Facebook SDK Integration
Wichtige Android-Konfiguration:
1. SHA-1-Fingerprint ermitteln (erforderlich für Google):
# For debug builds (development)
cd android
./gradlew signingReport
# Look for the SHA1 fingerprint under "Variant: debug"
# Add this SHA1 to your Google Cloud Console Android OAuth client
2. AndroidManifest.xml konfigurieren - Hinzufügen zu android/app/src/main/AndroidManifest.xml:
<!-- Internet permission -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Facebook configuration -->
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id"/>
<meta-data
android:name="com.facebook.sdk.ClientToken"
android:value="@string/facebook_client_token"/>
3. Facebook-Ressourcen hinzufügen zu android/app/src/main/res/values/strings.xml:
<string name="facebook_app_id">YOUR_FACEBOOK_APP_ID</string>
<string name="facebook_client_token">YOUR_FACEBOOK_CLIENT_TOKEN</string>
Folge den verlinkten Plattform-Guides für die vollständige Android-Konfiguration, einschließlich der Einrichtung der Google Play Services und der Konfiguration des Package-Namens.
Schritt 9: Supabase-Datenbank mit authentifizierten Usern nutzen
Sobald die User authentifiziert sind, kannst du die Supabase-Datenbank mit Row Level Security (RLS) nutzen:
// Example: Fetch user profile
async function getUserProfile() {
const { data: user } = await supabase.auth.getUser();
if (user) {
const { data, error } = await supabase
.from('profiles')
.select('*')
.eq('id', user.user.id)
.single();
return data;
}
}
// Example: Update user profile
async function updateUserProfile(updates: any) {
const { data: user } = await supabase.auth.getUser();
if (user) {
const { data, error } = await supabase
.from('profiles')
.update(updates)
.eq('id', user.user.id);
return data;
}
}
Wichtige Sicherheitsaspekte
- Gib niemals sensible Keys preis in deinem Client code
- Nutze Umgebungsvariablen für die Konfiguration
- Aktiviere Row Level Security in Supabase
- Token validieren bei Bedarf im Backend
- Token-Refresh handhaben automatisch mit Supabase
Bekannte Probleme und Troubleshooting
Nonce-Mismatch bei Google (besonders iOS)
Falls Supabase einen Nonce-Fehler zurückgibt, hat Google eventuell ein gecachtes ID-Token gesendet. Logge dich über das Plugin bei Google aus, versuche es erneut und stelle sicher, dass du die nonceDigest zu SocialLogin.login und rawNonce zu signInWithIdToken. Die Beispiel-App Wiederholungsversuche nach SocialLogin.logout.
Token-Audience-Fehler
Registriere jede Google Client ID (Web, iOS, Android) im Supabase Google Provider. Der aud Claim im ID-Token muss mit einer davon übereinstimmen.
OAuth-Redirect-Tutorials vs. dieser Guide
Blog posts that use signInWithOAuth in einer WebView auf Mobilgeräten fehlschlagen, wenn der Redirect Safari statt deiner App öffnet. Nutze lieber natives Login + signInWithIdToken für Capacitor, oder folge der Social Login Web-Konfiguration für Browser-Redirects.
Plattformspezifische Checks
- iOS: Bundle ID und URL Schemes aus Google iOS Setup
- Android: SHA-1 Fingerprints in Google Android Setup
- Siehe Plugin-Troubleshooting für gebündelte Fixes
Token-Mismatch und Netzwerkfehler
- Provider-Credentials in Google Cloud, Supabase und
SocialLogin.initialize - Loading- und Error-States in React (siehe
LoginPaneloben)
Fazit
Du hast nun ein vollständiges Authentifizierungssystem, das das robuste Backend von Supabase mit nativen Social-Login-Funktionen kombiniert. Dieses Setup bietet:
- Sichere, native Social-Authentifizierung
- Nahtloses Token-Management
- Echtzeit-Datenbankintegration
- Plattformübergreifende Kompatibilität
Die Kombination aus Supabase und dem Capgo Social Login Plugin bietet eine leistungsstarke, skalierbare Authentifizierungslösung für deine Capacitor Apps.
Für fortgeschrittene Features wie Multi-Faktor-Authentifizierung oder Custom Claims, schau dir die Supabase-Dokumentation an und Social Login Plugin-Dokumentation.
Weiterlesen: Supabase Authentication mit dem Capacitor Social Login Plugin einrichten
Wenn du es nutzt Supabase Authentication mit dem Capacitor Social Login Plugin einrichten Um Authentifizierungs- und Account-Flows zu planen, verbinde es mit @capgo/capacitor-social-login für die Implementierungsdetails in @capgo/capacitor-social-login, @capgo/capacitor-passkey für die Implementierungsdetails in @capgo/capacitor-passkey, @capgo/capacitor-native-biometric für die Implementierungsdetails in @capgo/capacitor-native-biometric, Zwei-Faktor-Authentifizierung für die Implementierungsdetails zur Zwei-Faktor-Authentifizierung, und SSO (Enterprise) für die Implementierungsdetails zu SSO (Enterprise).