App de Supabase en el App Store y Google Play: la lista de comprobación completa
Lovable, Bolt, Tempo, Hostinger Horizons y la mayoría de los proyectos de Cursor llevan Supabase por debajo. Supabase funciona perfectamente dentro de una app WebViewGold, pero unos pocos ajustes dan por hecho, sin avisar, que estás en una pestaña del navegador. Esta lista los repasa uno a uno en el orden en que te los encontrarás.
Desde $109 de pago único por plataforma, o deja que nuestro equipo lo haga todo desde $698.
Garantía de aprobación – o te devolvemos el dinero en 14 días
Sin programar
Pago único, actualizaciones gratuitas
Soporte humano 24/7
Hecho en Alemania desde 2014 · ISO 27001
9:41
Tu app
Tu appYa en tu bolsillo
App Store · Google Play Aprobada
1. Configuración de auth: Site URL y URLs de redirección
Panel de Supabase → Authentication → URL Configuration. Estos valores deciden adónde llega cada enlace de correo y cada callback de OAuth.
Site URL = tu dominio de producción (https://app.yourbrand.com), nunca la vista previa de lovable.app ni localhost. La guía del dominio propio explica por qué la app debe cargar un dominio tuyo.
Redirect URLs: añade cada ruta de callback que uses (https://app.yourbrand.com/auth/callback, /reset-password, /**). Elimina las URLs de túneles y vistas previas antes del lanzamiento.
Las plantillas de correo usan {{ .SiteURL }} y {{ .RedirectTo }}; comprueba que los correos de confirmación, de magic link y de recuperación apuntan a tu dominio.
Las sesiones persisten como en un navegador mientras las opciones de borrado de caché sigan desactivadas en WebViewGold (deletecache en Config.swift, CLEAR_CACHE_ON_STARTUP en Config.java).
2. Inicio de sesión social: Google y Apple
La Directriz 4.8 dice: si ofreces inicio de sesión con Google, también debes ofrecer Sign in with Apple (o una opción equivalente centrada en la privacidad).
Google: mantén el proveedor de Supabase y añade el helper de WebViewGold
Google rechaza OAuth dentro de WebViews incrustadas (el error "disallowed_useragent"). El Social Login Helper de WebViewGold lo resuelve sin cambios de código: define google_login_helper_triggers en Config.swift como ["https://accounts.google.com", "https://accounts.youtube.com"] y GOOGLE_LOGIN_HELPER_TRIGGERS en Config.java; el inicio de sesión se ejecuta entonces en una ventana dedicada con un user agent aceptado. Detalles en la guía de disallowed_useragent.
Apple: activa el proveedor en Supabase
Apple Developer: un App ID con la capacidad Sign in with Apple, un Services ID cuya URL de retorno sea https://YOUR-PROJECT.supabase.co/auth/v1/callback (o tu dominio de auth propio) y una clave .p8. Supabase: Authentication → Providers → Apple con el Services ID, el Team ID, el Key ID y el client secret generado. El secret es un JWT que caduca como máximo a los seis meses; pon un recordatorio en tu calendario.
Añade el botón en la app web
supabase.auth.signInWithOAuth({ provider: "apple", options: { redirectTo: "https://app.yourbrand.com/auth/callback" } }). Muestra el botón de Apple al menos con la misma prominencia que el de Google. WebViewGold detecta appleid.apple.com automáticamente; no hace falta configurar ningún helper.
Prueba ambos en un iPhone real
Completa el inicio de sesión con Google y con Apple en la compilación de TestFlight, incluida una cuenta totalmente nueva con una dirección de reenvío "Ocultar mi correo" de Apple.
3. Magic links y restablecimiento de contraseña mediante Universal Links
Un magic link abierto desde Mail acaba por defecto en Safari: el usuario inicia sesión en el sitio web, pero no en la app. Los Universal Links (iOS) y los App Links (Android) envían a la app los enlaces de tu dominio. Aloja /.well-known/apple-app-site-association y /.well-known/assetlinks.json en la carpeta pública de tu proyecto, añade la capacidad Associated Domains (applinks:app.yourbrand.com) y pon ShowExternalLink en true en Config.swift; en Android activa IS_DEEP_LINKING_ENABLED en Config.java y añade el dominio al intent filter de AndroidManifest.xml. La documentación de Universal Links y la documentación de App Links tienen los pasos exactos.
En el lado de Supabase, usa el flujo PKCE (predeterminado en supabase-js v2) y llama a exchangeCodeForSession en tu página de callback. Desactiva el seguimiento de clics en los correos de auth, porque un dominio de seguimiento en el enlace anula la asociación. La guía de deep links explica cómo probarlo.
¡Una forma estupenda de convertir tu web app en una app nativa! Entrega rápida y una manera genial de llevar tus apps a las tiendas sin tener que desarrollar una app nativa completa.
Kevin Joling · FlightConnections & TrainConnections · Trustpilot
4. Edge function para eliminar la cuenta
La Directriz 5.1.1(v) de Apple y la política de eliminación de cuentas de Google exigen una forma de eliminar la cuenta y sus datos desde la app. El cliente no puede eliminar un usuario de auth; una pequeña edge function con la service role key sí puede. Conecta a ella un botón "Eliminar cuenta", cierra después la sesión del usuario y añade una página pública /delete-account (Google pide esa URL). Flujo completo: la guía de eliminación de cuentas.
typescript
// supabase/functions/delete-account/index.ts
import { createClient } from "npm:@supabase/supabase-js@2";
Deno.serve(async (req) => {
const authHeader = req.headers.get("Authorization") ?? "";
const userClient = createClient(Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_ANON_KEY")!, {
global: { headers: { Authorization: authHeader } },
});
const { data: { user }, error } = await userClient.auth.getUser();
if (error || !user) return new Response("Unauthorized", { status: 401 });
const admin = createClient(Deno.env.get("SUPABASE_URL")!, Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!);
await admin.from("profiles").delete().eq("id", user.id); // o usa ON DELETE CASCADE hacia auth.users
const { error: delError } = await admin.auth.admin.deleteUser(user.id);
if (delError) return new Response(delError.message, { status: 500 });
return new Response(JSON.stringify({ ok: true }), { headers: { "Content-Type": "application/json" } });
});
5. Datos: RLS, subidas a Storage y privacidad
Row Level Security en cada tabla con datos de usuarios. Las herramientas a veces generan políticas "allow all" para que una demo funcione; revísalas en Table editor → Policies antes del lanzamiento.
Storage: buckets privados con URLs firmadas para los archivos de los usuarios; buckets públicos solo para recursos realmente públicos.
Las subidas desde la WebView funcionan sin más: un input de archivo estándar (accept="image/*") abre el selector de fotos nativo o la cámara. Escribe textos de permiso reales para la cámara y la fototeca en Info.plist y elimina los permisos que no uses.
La anon key en el cliente está bien por diseño; la service role key solo debe estar en edge functions y en código de servidor.
App Privacy (Apple) y Data safety (Google): una app de Supabase recopila como mínimo el correo, el ID de usuario y el contenido del usuario; menciona a Supabase como encargado del tratamiento en tu política de privacidad. La guía de privacidad tiene las respuestas típicas.
6. IDs de push de los usuarios y el webhook de RevenueCat
Dos puntos de contacto con el backend que hacen personales las funciones nativas.
Guarda el ID de suscripción push de cada usuario
Tras el inicio de sesión, navega a getonesignalplayerid://; WebViewGold define window.onesignalplayerid (o activa autoInjectVariable / AUTO_INJECT_VARIABLES para obtenerlo sin la llamada). Haz un upsert en profiles.push_id y envía notificaciones dirigidas desde una edge function a través de la API REST de OneSignal. Firebase y Pushwoosh funcionan igual.
Recibe los eventos de RevenueCat
Crea una edge function como endpoint del webhook, verifica la cabecera Authorization que definiste en RevenueCat y escribe subscriptions(user_id, entitlement, expires_at, store). Como tu app web lanza las compras con revenuecat://purchase?external_id=USER_ID&product=PRODUCT, el app_user_id del webhook es exactamente tu ID de usuario de Supabase.
Controla el acceso a las funciones en el servidor
Las comprobaciones premium leen la tabla subscriptions a través de RLS, nunca un flag en localStorage. Los webhooks de Stripe de la versión web escriben en la misma tabla, así que una sola comprobación cubre ambos canales (guía de RevenueCat).
Preguntas frecuentes
¿Necesito un SDK nativo de Supabase o un flujo de auth distinto para la app?
No. El SDK web que ya usas funciona dentro de la WebView. Lo único que se añade es el Social Login Helper de WebViewGold para Google y la configuración de Universal Links para los enlaces de correo.
¿Supabase Realtime y los websockets funcionan dentro de WebViewGold?
Sí. WKWebView y la WebView de Android admiten websockets, así que las suscripciones de Realtime se comportan como en el navegador.
¿Los usuarios mantendrán la sesión iniciada entre aperturas de la app?
Sí, mientras las opciones de borrado de caché de los archivos Config sigan desactivadas. supabase-js renueva la sesión exactamente igual que en la web.
¿Los magic links funcionan sin Universal Links?
Inician la sesión del usuario, pero en Safari y no en la app. En una app centrada en el inicio de sesión, eso confunde lo suficiente como para que merezca la pena dedicar una hora a configurarlo.
Tres formas de llevar tu app a las tiendas
El mismo resultado, con distinta cantidad de trabajo por tu parte. Las tres incluyen la garantía de aprobación y soporte humano 24/7.
Hazlo tú mismo
$109 por plataforma, pago único
La licencia de WebViewGold: un proyecto de Xcode o Android Studio listo para usar. Pega tu URL, define nombre e icono, activa funciones, compila y envía. Actualizaciones gratuitas para siempre.
Sin Mac, sin Xcode, sin Android Studio: configura en el navegador, compilamos ambas apps en la nube y las entregamos a App Store Connect y a Play Console.
Envíanos tu URL y tu icono. Nuestro equipo configura, compila y entrega tu app en 72 horas, en marca blanca y con los proyectos fuente. Ambas plataformas por $1,158.
Los reembolsos se conceden bajo las condiciones indicadas en nuestras FAQ: un rechazo por motivos ajenos al contenido por parte de Apple y/o Google, reclamado dentro de los 14 días posteriores a la compra.