El stack Claude Code + Supabase en el App Store y en Google Play
Claude Code y Supabase forman una pareja natural: el agente escribe el esquema, las políticas y las edge functions, y Supabase las ejecuta. Dentro de una app WebViewGold hay cinco cosas que requieren atención y que un navegador nunca te pidió: la autenticación en un WebView, los magic links, la eliminación de cuenta, los ID de usuario de push y las compras en la tienda. Esta es la lista de configuración.
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
Supabase Auth dentro de un WebView
El inicio de sesión con correo y contraseña funciona sin cambios: la sesión vive en el almacenamiento del WebView y se mantiene mientras el envoltorio no lo borre (deletecache en Config.swift y CLEAR_CACHE_ON_STARTUP en Config.java se quedan en false). Con OAuth es distinto. Google se niega a completar un inicio de sesión dentro de un WebView integrado (el error disallowed_useragent), por eso WebViewGold incluye un Social Login Helper: enumeras los prefijos de URL del flujo del proveedor y el envoltorio abre esa parte en una ventana de inicio de sesión dedicada que el proveedor acepta, y después vuelve a tu app. Para Supabase con Google, el activador es https://accounts.google.com, definido en google_login_helper_triggers (Config.swift) y GOOGLE_LOGIN_HELPER_TRIGGERS (Config.java). Sign in with Apple no necesita nada: el envoltorio detecta appleid.apple.com automáticamente.
Es decir: activa el proveedor de Apple en el panel de Supabase (Services ID, clave, Team ID, URL de retorno), añade el botón junto al de Google para cumplir la Directriz 4.8 y pide a Claude Code que conecte signInWithOAuth para ambos con la redirección apuntando a tu dominio de producción.
Magic links que se abren dentro de la app
Un magic link en un correo se abre por defecto en el navegador. Los Universal Links y los App Links lo envían a la app.
Sirve los archivos de asociación
Pide a Claude Code que añada al proyecto web /.well-known/apple-app-site-association (JSON con tu Team ID y tu bundle ID, servido sin extensión de archivo y con un content type JSON) y /.well-known/assetlinks.json (tu nombre de paquete y la huella del certificado de firma). En Next.js eso es la carpeta public más una regla de cabeceras.
Activa la capacidad en el envoltorio
iOS: Associated Domains con applinks:app.example.com en Xcode y ShowExternalLink en true en Config.swift. Android: el intent filter de tu dominio en AndroidManifest.xml y IS_DEEP_LINKING_ENABLED en true en Config.java. Más detalles en la documentación de Universal Links y en la documentación de App Links.
Apunta Supabase a tu dominio
Define la Site URL y la lista de redirecciones permitidas como https://app.example.com/auth/callback. Así el enlace del correo llega a tu dominio, que el sistema operativo entrega a la app cuando está instalada.
Ofrece un código como alternativa
Algunas apps de correo abren los enlaces en su propio navegador. Pide a Claude Code que añada una opción de OTP de seis dígitos (añade la variable del token a la plantilla del correo de magic link en el panel de Supabase) para que un usuario que acabe en Safari pueda terminar igualmente dentro de la app. Si usas el flujo PKCE, esta alternativa importa todavía más, porque el code verifier solo existe en el contexto que inició el inicio de sesión.
La eliminación de cuenta como edge function
Apple 5.1.1 y Google Play exigen la eliminación dentro de la app; Supabase la convierte en una sola función, con la clave service-role guardada en el servidor.
Prompt para Claude Code
Implementa la eliminación de cuenta para esta app de Supabase tal como exigen Apple y Google Play.
1. Crea una edge function de Supabase delete-account que: lea el JWT del usuario de la cabecera Authorization y lo verifique con el cliente anon; después, usando un cliente service-role creado solo dentro de la función, borre las filas del usuario en cada tabla que haga referencia a auth.users (enuméralas a partir del esquema; donde falten, prefiere claves foráneas con ON DELETE CASCADE y escribe la migración), elimine los archivos del usuario de los buckets de storage y, por último, llame a auth.admin.deleteUser(userId). Devuelve 204 si todo va bien y un error claro en caso contrario.
2. En la app web, añade Ajustes - Eliminar cuenta con un diálogo de confirmación que explique qué se borra, llame a la función con la sesión actual, cierre la sesión y muestre una pantalla de confirmación. Si existen suscripciones de RevenueCat, indica al usuario que primero las cancele en los ajustes de App Store o Google Play.
3. Añade una página pública /delete-account que explique el proceso a los usuarios que no tienen la app.
4. Añade una frase sobre la eliminación en /privacy.
5. Escribe un test que cree un usuario desechable, inserte filas, llame a la función y compruebe que todo ha desaparecido.
¡Gran trabajo! Nunca tuve que usar código para nada, pero logré trabajar con esto y tener mi App lista. ¡Fácil y rápido! ¡También con gran ayuda de los creadores!
La clave anon está en tu bundle de cliente por diseño, y cualquiera puede descargar una app publicada. Row Level Security es lo que hace que eso sea seguro.
Cada tabla del esquema public tiene RLS activado y políticas explícitas para select, insert, update y delete con auth.uid(). Pide a Claude Code que enumere las tablas sin RLS y que escriba las políticas que faltan.
Los buckets de storage también tienen políticas; un bucket público es público para todo el mundo, incluidas personas que nunca abrieron tu app.
La clave service-role solo aparece en edge functions y código de servidor, nunca en el bundle de cliente de Vite o Next.js. Búscala con grep en la salida de la build.
Las vistas y las funciones RPC respetan los permisos de quien las llama; marca las funciones como security invoker salvo que necesites deliberadamente derechos de definer.
Límites de frecuencia en la autenticación y en las llamadas RPC costosas, porque las apps de las tiendas atraen tráfico automatizado en cuanto aparecen publicadas.
Guardar el ID de suscripción push en el perfil
Con autoInjectVariable / AUTO_INJECT_VARIABLES en true, el envoltorio inyecta onesignalplayerid en cada página; si no, solicítalo con getonesignalplayerid://. Guárdalo en el perfil para que una edge function pueda dirigirse a un usuario concreto.
javascript
// after login, inside the native app only
import { supabase } from "./supabase";
import { isNativeApp, readInjected, callNative } from "./native";
export async function syncPushSubscription(userId) {
if (!isNativeApp()) return;
let playerId = window.onesignalplayerid; // present when auto-inject is on
if (!playerId) {
callNative("getonesignalplayerid://");
playerId = await readInjected("onesignalplayerid", 3000).catch(function () { return null; });
}
if (!playerId) return;
await supabase.from("profiles").update({ onesignal_player_id: playerId }).eq("id", userId);
}
// RLS policy to pair with it (SQL):
// create policy "users update own profile" on profiles for update
// using (auth.uid() = id) with check (auth.uid() = id);
El webhook de RevenueCat y el resto del flujo de dinero
Compra desde la app web
Dentro de la app, el botón para mejorar el plan navega a revenuecat://purchase?external_id=SUPABASE_USER_ID&product=PRODUCT_ID. Pasar el ID de usuario de Supabase como external_id es lo que permite al webhook asociar la compra a una fila.
Edge function para el webhook
Prompt: "Crea una edge function revenuecat-webhook que verifique la cabecera Authorization configurada en RevenueCat, haga upsert del evento en una tabla subscriptions con app_user_id como clave y defina un flag is_active según el tipo de evento." El cliente lee el entitlement a través de RLS, nunca a partir del resultado de la compra en el cliente.
La web sigue con Stripe
Los navegadores pueden seguir usando Stripe. Guarda un único modelo de entitlements (una tabla subscriptions con una columna source) para que las funciones se desbloqueen igual sin importar dónde pagó el usuario. Consulta la guía de configuración de RevenueCat.
Comisión
Small Business Program de Apple y nivel del 15% de Google: 15% de comisión por debajo de $1M al año y 30% por encima. Solicítalo en ambas consolas e indícalo en RevenueCat.
Preguntas frecuentes
¿Necesito los SDK nativos de Supabase para las apps de las tiendas?
No. Lo que se ejecuta dentro de WebViewGold es la app web con supabase-js. La capa nativa solo añade push, biometría, compras y deep links mediante esquemas de URL.
¿La sesión de Supabase sobrevive a los reinicios de la app?
Sí, siempre que el envoltorio no borre el almacenamiento al arrancar. Mantén deletecache (iOS) y CLEAR_CACHE_ON_STARTUP (Android) en false y define una duración de sesión razonable en el panel de Supabase.
El inicio de sesión con Google funciona en el navegador pero no en la app. ¿Por qué?
Google bloquea los WebViews integrados. Define los activadores del Social Login Helper para accounts.google.com en ambas configuraciones de WebViewGold; el envoltorio completará entonces el inicio de sesión en una ventana aceptada y volverá a tu app.
¿Claude Code puede escribir las políticas RLS de forma segura?
Escribe buenos primeros borradores si le das el esquema y las reglas de acceso en lenguaje natural. Revisa cada política, prueba con dos usuarios distintos y nunca publiques una tabla sin RLS solo porque una demo funcionó.
¿Dónde verifico la compra, en el cliente o en el servidor?
En el servidor. El webhook de RevenueCat hacia una edge function es la fuente de verdad; el cliente solo lee la fila resultante. Los flags del lado del cliente se pueden falsificar en cualquier app descargable.
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.