Lanza el inicio de sesión nativo de Google y Apple en una React app, respaldada por Autenticación de Supabase, y envuelve la misma UI en Capacitor sin lidiar con redirecciones del navegador móvil. Social Login con Capgo (@capgo/capacitor-social-login) gestiona las hojas nativas del proveedor; intercambias el ID token del proveedor por una sesión de Supabase con signInWithIdToken.
Este artículo amplía nuestra guía de Supabase + Social Login con un React + Vite tutorial completo (estructura del proyecto, providers, rutas, configuración de Capacitor). Para dashboards de proveedores y keys de plataforma, sigue usando la documentación de integración de Supabase y la configuración general de Google + Supabase. Posts relacionados: Inicio de sesión con Google usando Capacitor, Inicio de sesión con Apple usando Capacitor, y opciones de autenticación en Capacitor.
Tabla de contenidos
- Qué vas a construir
- Flujo de autenticación general
- Aplicación base en React (Vite)
- Proyecto de Supabase y proveedor de Google
- Configurar proveedores en Supabase
- Inicializar el plugin de Social Login
- Cliente de Supabase y capa de auth en React
- UI de login y rutas protegidas
- Añade Capacitor a la app de React
- Configuración de la plataforma
- Acceso a la base de datos con RLS
- Problemas conocidos y solución de errores
- Consideraciones de seguridad
Qué vas a construir
- Una Vite + React + TypeScript web app con botones de sign-in y vista de debug
- Autenticación de Supabase sesiones creadas desde native Google (y opcional Apple) tokens ID
- El mismo bundle ejecutándose en Capacitor en iOS y Android
- Un flujo de Google seguro contra nonce, alineado con el app de ejemplo del plugin
Flujo de autenticación general
Con @capgo/capacitor-social-login, la app móvil realiza necesitas confiar en signInWithOAuth redirecciones dentro del WebView. El SDK nativo devuelve un Token de ID; Supabase lo valida y emite su propio JWT.

En web, puedes seguir usando el mismo plugin (ver configuración web de Google). Gestiona las URLs de retorno de OAuth en tu router si más adelante añades un fallback de navegador.
Aplicación base en React (Vite)
Crea una app nueva (o reutiliza un codebase de React):
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
Inicia el servidor de dev:
bun run dev

Estructura de carpetas objetivo:

Añade las variables de entorno en .env.local (nunca hagas commit de secrets):
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
¿Por qué usar Supabase con Social Login?
Supabase ofrece un backend-as-a-service robusto con autenticación integrada, mientras que el @capgo/capacitor-social-login plugin ofrece autenticación social nativa en iOS, Android y web. Para una integración más estrecha con Supabase, @capgo/capacitor-supabase añade helpers de auth nativa y acceso JWT. Juntos, ofrecen:
- Autenticación social fluida
- Gestión segura de tokens
- Compatibilidad multiplataforma
- Integración de base de datos en tiempo real
- Gestión de usuarios integrada
Requisitos
Antes de empezar, asegúrate de tener:
- Un proyecto Capacitor configurado
- Una cuenta y proyecto de Supabase
- Cuentas de desarrollador para tus proveedores sociales (Google, Apple, Facebook)
Paso 1: Instalar y configurar el plugin de Social Login
Primero, instala el plugin de Capgo Social Login:
bun add @capgo/capacitor-social-login
Ejecuta bunx cap sync después de añades Capacitor y las plataformas nativas en Añade Capacitor a la app de React. El tutorial solo para Vite funciona en el navegador antes de ese paso.
Consulta la Social Login y Supabase plugin pages for platform-specific setup.
Paso 2: Configurar el proyecto de Supabase

Crea y configura tu proyecto de Supabase
-
Crea un proyecto en Supabase:
- Ve a supabase.com y regístrate o inicia sesión
- Haz clic “Nuevo proyecto”
- Elige tu organización
- Introduce un Nombre del proyecto (ej., “MyApp Auth”)
- Configura un Contraseña de la base de datos (guárdala de forma segura)
- Selecciona tu Región (elige la más cercana a tus usuarios)
- Haz clic “Crear nuevo proyecto”
-
Obtén las credenciales de tu proyecto:
- Una vez creado, ve a Configuración > API
- Copia tu URL del proyecto (ej.,
https://your-project-ref.supabase.co) - Copia tu anon public clave de API
- Guárdalos para usarlos después en tu app
Configurar ajustes de autenticación
-
Configura los ajustes generales de autenticación:
- Ve a Autenticación > Configuración
- En Configuración general:
- Configurar URL del sitio a la URL de tu app (ej.,
https://yourdomain.comohttp://localhost:3000para desarrollo) - Añadir otras URLs de redirección si es necesario:
http://localhost:3000 https://yourdomain.com capacitor://localhost (for mobile apps)
- Configurar URL del sitio a la URL de tu app (ej.,
-
Configurar ajustes de email (opcional pero recomendado):
- En Configuración SMTP, configura tu proveedor de email
- Esto permite confirmaciones por email y restablecimiento de contraseñas
- Para desarrollo, puedes usar el servicio de email integrado
Habilitar proveedores de autenticación social
- Accede a la sección de proveedores:
- Ve a Autenticación > Proveedores en tu dashboard de Supabase
- Verás una lista de proveedores sociales disponibles
- Cada proveedor tiene un Activar opciones de configuración y toggle
Ahora configuremos cada proveedor social en detalle:
Paso 3: Configurar proveedores sociales en Supabase
Configuración de Google Authentication en Supabase
Primero, obtén tus credenciales de Google OAuth:
Sigue nuestra guía completa de configuración de Google: Configuración de Google Authentication
Esta guía cubre:
- Creación de un proyecto en Google Cloud
- Configuración de credenciales OAuth 2.0 para web, iOS y Android
- Configuración de la pantalla de consentimiento
- Obtención de los Client IDs y secrets necesarios
Tras completar la configuración de Google, configúralo en Supabase:
Sigue la Guía general de Supabase + Google para ver capturas de cada dashboard.
- Habilita el proveedor de Google en Supabase:
- En tu dashboard de Supabase, ve a Autenticación > Proveedores
- Busca Google y actívalo ON
- Añade la Web, iOS, y Android client IDs que creaste en Google Cloud (omite las plataformas que no publiques)
- Haz clic Guardar
Importante para este tutorial de React: cuando usas signInWithIdToken con @capgo/capacitor-social-login, sí necesitas necesitas necesitas los campos OAuth secret del cliente o callback URL para Google. Registra todos los client IDs que Supabase aceptará al validar los tokens de cada plataforma.
Configuración de Apple Authentication en Supabase
Obtén las credenciales de Apple:
Sigue nuestra guía detallada para configurar Apple: Configuración de Apple Authentication
Esta guía cubre:
- Configuración de tu cuenta de Apple Developer
- Creación de App IDs y Service IDs
- Configuración de la capacidad Sign in with Apple
- Generación de las private keys necesarias
- Configuración por plataforma para iOS, Android y Web
Tras completar la configuración de Apple, configúralo en Supabase:
- Habilitar el proveedor Apple en Supabase:
- Ve a Autenticación > Proveedores y activa Apple ON
- Completa la configuración:
- ID de cliente: Tu iOS App ID y tu Apple Service ID cuando lances ambas plataformas, separados por comas (por ejemplo
com.yourapp,com.yourapp.signin). Los tokens de iOS usan el App ID como audience; Android y web usan el Service ID. Consulta Configuración general de Supabase con Apple. - Para el flujo de este tutorial
signInWithIdTokencon Apple@capgo/capacitor-social-login, sí necesitas necesitas un client secret de OAuth o la URL de callback de Supabase OAuth en el formulario del proveedor de Apple.
- ID de cliente: Tu iOS App ID y tu Apple Service ID cuando lances ambas plataformas, separados por comas (por ejemplo
- Haz clic Guardar
Nota: La configuración de la autenticación de Apple es la más compleja debido a los requisitos de Apple para Service IDs, claves privadas y URLs de redirección específicas de cada plataforma. Sigue nuestra documentación con cuidado para cada plataforma.
Configurar la autenticación de Facebook en Supabase
Obtén las credenciales de Facebook:
Sigue nuestra guía completa para configurar Facebook: Configuración de la autenticación con Facebook
Esta guía cubre:
- Crear una cuenta de desarrollador de Facebook y una app
- Añadir el producto Facebook Login
- Configurar las URIs de redirección OAuth
- Obtener tu App ID, App Secret y Client Token
- Configuración específica de plataforma para iOS y Android
Después de completar la configuración de Facebook, configúrala en Supabase:
- Habilitar el proveedor de Facebook en Supabase:
- Ve a Autenticación > Proveedores y activa Facebook ACTIVADO
- Completa la configuración:
- ID de cliente: Tu Facebook App ID
- Secreto del cliente: Tu Facebook App Secret
- URL de redirección:
https://your-project-ref.supabase.co/auth/v1/callback(autocompletado)
- Haz clic “Guardar”
Importante: Asegúrate de añadir la URL de callback de Supabase (https://your-project-ref.supabase.co/auth/v1/callback) a tu app de Facebook URI de redireccionamiento de OAuth válidos en la configuración de Facebook Login.
Notas importantes de configuración de Supabase
Seguridad a nivel de fila (RLS):
- Después de configurar la autenticación, activa RLS en tus tablas
- Ve a Database > Tables y activa Habilitar RLS para cada tabla
- Crea políticas para controlar el acceso a los datos según los usuarios autenticados
Gestión de usuarios:
- Ver usuarios autenticados en Autenticación > Usuarios
- Monitorea eventos de autenticación en Autenticación > Logs
- Configura plantillas de email en Autenticación > Plantillas de correo electrónico
Prueba la configuración:
- Usa la herramienta de test de autenticación de Supabase
- Ve a Autenticación > Usuarios y haz clic en “Invitar usuario” para probar flujos de email
- Consulta la Logs sección para errores de autenticación
Paso 4: Configurar el plugin de Social Login
Con Supabase configurado, ahora debes preparar el plugin de Social Login con las credenciales correspondientes. Importante: El plugin requiere las credenciales OAuth de los proveedores originales (no desde Supabase), mientras Supabase gestiona la autenticación en el servidor.
Cómo funciona el flujo de autenticación
Antes de configurar, entiende el flujo:
- El plugin autentica con el proveedor social (Google/Apple/Facebook) de forma nativa
- El plugin recibe los tokens (access token, ID token) del proveedor
- Tu app envía estos tokens a Supabase usando
signInWithIdToken() - Supabase valida los tokens con el proveedor y crea una sesión de usuario
- Supabase devuelve su propio token JWT para las peticiones autenticadas de tu app
Configuración del plugin de Google
El plugin necesita tu ID de cliente web para todas las plataformas y, opcionalmente, un ID de cliente de iOS para funciones específicas de iOS:
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'
}
});
Puntos clave para Google:
- Usa la ID de cliente web (no los client IDs de Android/iOS) para el
webClientIdcampo - El plugin funcionará en todas las plataformas solo con el Web Client ID
- El
iOSClientIdes opcional y solo se usa para funciones de Google en iOS
Configuración del plugin de Apple
La configuración de Apple varía entre iOS y Android:
Para iOS (Sign in with Apple nativo):
await SocialLogin.initialize({
apple: {
// No additional configuration needed for iOS
// The plugin uses the native Apple Sign-In capability
}
});
Para Android/Web (requiere Service ID). Usa las mismas reglas de redirección que buildApplePluginConfig() en el tutorial de React:
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,
},
});
Puntos clave para Apple:
- iOS usa Sign in with Apple nativo (sin configuración extra)
- Android usa tu Service ID y la URL de
apple-signin-callbackSupabase Edge Function - Web usa tu Service ID y
window.location.href, que debe coincidir con las Apple Return URLs
Configuración del plugin de Facebook
Facebook requiere tu App ID y 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
}
});
Puntos clave para Facebook:
- Usa el mismo App ID que configuraste en Supabase
- El Client Token está en la configuración básica de tu App de Facebook
limitedLogin: trueactiva la función Limited Login de Facebook (solo iOS)- Importante: See our Guía de configuración de Facebook para info detallada de Limited Login, incluyendo ATT

Completar la inicialización del plugin
Así puedes inicializar todos los providers juntos:
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
}
});
}
Notas importantes:
- Llama a
initialize()una vez al iniciar la app, no antes de cada login - Solo necesitas configurar los providers que vayas a usar
- Las credenciales aquí son de los providers originales, no de Supabase
- Asegúrate de que las credenciales del proveedor coincidan con lo que configuraste en Supabase
Cliente de Supabase para React y capa de auth
Instala el cliente de Supabase si aún no lo has hecho:
bun add @supabase/supabase-js
Crea un único cliente para todo el árbol de React:
// 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,
},
});
Helpers de nonce para Google + Supabase
Supabase espera un nonce en bruto en signInWithIdToken y un digest SHA-256 enviado a Google. El Guía de Google con Supabase documenta el flujo completo. Helpers mínimos:
// 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 };
}
Conecta Social Login + Supabase en un módulo (patrón del ejemplo 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 por plataforma (ver Configuración general de Supabase con Apple, Android, Web):
- iOS:
buildApplePluginConfig()devuelve{}. El inicio de sesión nativo con Apple usa tu bundle ID. NoredirectUrl. - Android:
clientIdes tu Apple Service ID.redirectUrles tu Supabase Edge Function (apple-signin-callback). Despliega la función, configura el Apple Return URL en ese endpoint y añade el intent filter de deep link de la app para que el flujo pueda volver al WebView (Guía de Apple con Supabase en Android). - Web:
clientIdes tu Service ID.redirectUrleswindow.location.href, que debe coincidir con un Return URL en el Apple Developer Portal (Guía de Apple con Supabase en Web).
ensureSocialLoginInitialized() añade el apple proveedor solo cuando isAppleLoginConfigured() es true, así que una configuración solo de Google no envía credenciales vacías de Android o Apple web.
El plugin devuelve result.idToken en todas las plataformas (AppleProviderResponse en @capgo/capacitor-social-login). Registra tanto el iOS App ID como el Service ID en Supabase cuando lances para múltiples plataformas.
Expón el estado de la sesión a los componentes:
// 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;
}
UI de login en React y rutas protegidas

Panel de login:
// 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>
);
}
Vista de debug de la sesión (reemplaza con tu UI de cuenta real más tarde):
// 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>
);
}

Rutas con 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>
);
}
Monta la app en main.tsx como siempre. Tras un login correcto con el proveedor, onAuthStateChange actualizaciones session y React Router redirige al usuario a /account.
Opcional: Facebook
Facebook sigue el mismo signInWithIdToken patrón con el access token del plugin. Consulta configuración de Facebook y el bloque del proveedor en Paso 4.
Añade Capacitor a la app de React
Genera el bundle web y luego añade los proyectos nativos:
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

Sincroniza tras cada build web:
bun run build
bunx cap sync
Abre el IDE nativo cuando estés listo para probar en dispositivos:
bunx cap open ios
bunx cap open android
Completa los pasos de Google y Apple antes de probar en hardware:
Deep links y Universal Links
Los tutoriales que se ejecutan supabase.auth.signInWithOAuth dentro de un WebView suelen requerir Universal Links o App Links así que el SO devuelve el control a la app tras la redirección de Google. Native Google sign-in con un Token de ID evita ese bucle de redirección porque el plugin nunca abre un flujo de OAuth en el navegador. Apple en Android es distinto: sigue usando el redireccionamiento de la Edge Function y un deep link intent filter para que la WebView pueda reanudarse tras el login de Apple.
Aún puedes configurar deep links para otras funciones (emails de reset de contraseña, magic links, URLs de marketing). Añade las mismas rutas a Autenticación > Configuración de URL en Supabase y en tus apple-app-site-association / intent filters de Android al añadir esos flujos.
Paso 8: Configuración por plataforma
Configuración de iOS
Para instrucciones detalladas de iOS, consulta nuestras guías por plataforma:
- Configuración de Google en iOS - URL schemes, configuración de Info.plist
- Configuración de Apple en iOS - Configuración de la capacidad Sign in with Apple
- Configuración de Facebook en iOS (en la guía general de Facebook) - Configuración de SDK de Facebook
Resumen rápido - Añadir a 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>
Sigue las guías enlazadas para la configuración completa de iOS, incluyendo el proyecto de Xcode.
Configuración de Android
Para instrucciones detalladas de Android, consulta nuestras guías específicas:
- Configuración de Google en Android - Huellas SHA-1, configuración de Google Play Services
- Configuración de Apple en Android - Configuración del Service ID para Android
- Configuración de Facebook en Android (en la guía general de Facebook) - Integración de SDK con Facebook
Configuración esencial de Android:
1. Obtén tu huella digital SHA-1 (requerido para 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. Configura AndroidManifest.xml - Añadir a 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. Añade recursos de Facebook a 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>
Sigue las guías de la plataforma para la configuración completa de Android, incluyendo Google Play Services y el package name.
Paso 9: Usar la base de datos Supabase con usuarios autenticados
Una vez autenticados los usuarios, puedes usar la base de datos de Supabase con Row Level Security (RLS):
// 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;
}
}
Consideraciones de seguridad importantes
- Nunca expongas claves sensibles en el code de tu cliente
- Usa variables de entorno para la configuración
- Activa Row Level Security en Supabase
- Valida los tokens en tu backend si es necesario
- Gestiona el refresh de tokens automáticamente con Supabase
Problemas conocidos y solución de errores
Error de nonce en Google (especialmente en iOS)
Si Supabase devuelve un error de nonce, es posible que Google haya devuelto un ID token en caché. Cierra sesión en Google mediante el plugin, reintenta una vez y confirma que pasas nonceDigest a SocialLogin.login y rawNonce a signInWithIdToken. El app de ejemplo reintentos después de SocialLogin.logout.
Errores de audiencia del token
Registra cada client ID de Google (web, iOS, Android) en el proveedor de Google de Supabase. El aud claim en el ID token debe coincidir con uno de ellos.
Tutoriales de redirección OAuth vs esta guía
Posts del blog que usan signInWithOAuth en una WebView puede fallar en móviles si el redirect abre Safari en vez de tu app. Prefiere login nativo + signInWithIdToken para Capacitor, o sigue configuración web de Social Login para redirecciones de navegador.
Comprobaciones por plataforma
- iOS: bundle ID y URL schemes de configuración de Google en iOS
- Android: huellas SHA-1 en configuración de Google en Android
- Ver solución de problemas del plugin para correcciones consolidadas
Discrepancia de tokens y errores de red
- Sincroniza las credenciales entre Google Cloud, Supabase y
SocialLogin.initialize - Maneja estados de carga y error en React (ver
LoginPanelarriba)
Conclusión
Ya tienes un sistema de autenticación completo que combina el backend robusto de Supabase con capacidades de social login nativo. Esta configuración ofrece:
- Autenticación social nativa y segura
- Gestión de tokens sin fricciones
- Integración de base de datos en tiempo real
- Compatibilidad multiplataforma
La combinación de Supabase y el plugin Capgo Social Login ofrece una solución de autenticación potente y escalable para tus apps Capacitor.
Para funciones más avanzadas como autenticación multifactor o claims personalizados, consulta la documentación de Supabase y la documentación del plugin Social Login.
Continuar desde Configurar autenticación de Supabase con el plugin Social Login de Capacitor
Si estás usando Configurar autenticación de Supabase con el plugin Social Login de Capacitor para planificar los flujos de autenticación y de cuenta, conéctalo con @capgo/capacitor-social-login para los detalles de implementación en @capgo/capacitor-social-login, @capgo/capacitor-passkey para el detalle de implementación en @capgo/capacitor-passkey, @capgo/capacitor-native-biometric para el detalle de implementación en @capgo/capacitor-native-biometric, Autenticación de dos factores para el detalle de implementación en la autenticación de dos factores, y SSO (Enterprise) para el detalle de implementación en SSO (Enterprise).