Saltar al contenido
← Volver al blog
appsseguridad

¿No se suben archivos en tu app de Lovable? Arregla Storage

Por qué fallan las subidas o no se ven las imágenes en tu app de Lovable: políticas, límites de tamaño, buckets y archivos privados, y cómo arreglarlo.

Por Equipo Devonauts6 min de lectura
Read in English →
Un hombre mira por una cámara de fotos en su escritorio junto a una laptop con una cuadrícula de fotos

Cuando las subidas de archivos fallan en una app de Lovable, casi siempre es por una de cuatro cosas: ninguna política de storage permite que el usuario con sesión escriba en ese bucket, el archivo supera el límite de tamaño, el código sube a un bucket o una ruta que no coincide con la política, o la subida funciona pero el archivo no se puede mostrar porque el bucket es privado. La petición que falla en la pestaña Network del navegador te dice cuál, normalmente en una sola línea.

En esta guía vas a ver cómo leer ese error, cómo funcionan los permisos de storage en Lovable Cloud y en tu propio Supabase, la política que necesitan casi todas las apps y cómo comprobar que un usuario no puede abrir los archivos de otro.

¿Cómo sé por qué falló la subida?

  1. Abre la app, abre las herramientas de desarrollo (Inspeccionar) y entra a la pestaña Network.
  2. Vuelve a subir el archivo. Busca la petición a una dirección que contenga /storage/v1/object/.
  3. Lee el código de estado y el cuerpo de la respuesta.
Lo que vesCausa probable
400 o 403 con new row violates row-level security policyNinguna política permite a este usuario subir a este bucket o ruta
413, o un mensaje de que el objeto supera el tamaño máximoEl archivo pasa el límite del bucket o del proyecto
Un error de bucket no encontradoEl nombre del bucket en el código no coincide con el real
Un error de tipo de archivo (MIME)El bucket solo acepta ciertos formatos
La subida funciona, la imagen se ve rotaEl bucket es privado y la app usa una URL pública

En Lovable Cloud, More → Cloud → Logs tiene una vista Storage logs con los mismos eventos. En tu propio Supabase, usa los registros de storage del panel.

¿Por qué storage rechaza la subida?

Los archivos viven en una tabla llamada storage.objects que, como cualquier tabla, está protegida con row level security. La documentación de control de acceso de Storage lo dice claro: storage no permite ninguna subida a un bucket sin políticas. Un bucket sin políticas está cerrado para todos, salvo para el código de servidor que use la clave secreta.

Cada acción necesita su permiso:

  • Subir un archivo nuevo: una política INSERT.
  • Sobrescribir un archivo (un "upsert", típico en fotos de perfil): INSERT, más SELECT y UPDATE.
  • Listar o descargar de un bucket privado: SELECT.
  • Borrar: DELETE.

El caso clásico es el de la foto de perfil que se sube bien la primera vez y falla la segunda: el código usa upsert: true y solo existe la política de inserción.

¿Qué política necesita casi cualquier app?

El patrón más común: cada usuario maneja los archivos de una carpeta con el nombre de su propio ID de usuario. En SQL:

create policy "Usuarios suben a su propia carpeta"
on storage.objects for insert to authenticated
with check (
  bucket_id = 'avatars'
  and (storage.foldername(name))[1] = (select auth.uid()::text)
);

create policy "Usuarios leen sus propios archivos"
on storage.objects for select to authenticated
using (
  bucket_id = 'avatars'
  and (storage.foldername(name))[1] = (select auth.uid()::text)
);

Agrega políticas update y delete equivalentes si los usuarios pueden reemplazar o borrar archivos. Para que funcione, el código tiene que subir a una ruta que empiece con el ID del usuario:

await supabase.storage.from("avatars").upload(`${user.id}/avatar.png`, archivo, { upsert: true });

Si el código sube a avatar.png o a public/avatar.png, la política lo rechaza, y hace bien. Ese desfase entre la ruta y la política es uno de los errores de subida más comunes en código generado con IA.

En Lovable casi nunca escribes esto a mano. Describe la regla en el chat ("cada usuario puede subir y reemplazar solo su propia foto de perfil, guardada en una carpeta con su ID de usuario") y después revisa las políticas que creó Lovable en More → Cloud → Database. Si quieres entender bien cómo funcionan, lee la guía de Row Level Security de Supabase en Lovable y Bolt.

¿Cuáles son los límites de tamaño?

Dependen de dónde esté tu storage:

  • Lovable Cloud: archivos de hasta 2 GB por defecto. Puedes cambiar el Upload size limit, hasta 5 GB, arriba de More → Cloud → Storage.
  • Tu propio proyecto de Supabase: un límite global en los ajustes de Storage, que en el plan Free no puede pasar de 50 MB y en Pro o superior llega hasta 500 GB. Cada bucket puede tener un límite más bajo, nunca más alto.

En archivos grandes también importa el método. Supabase recomienda la subida estándar para archivos chicos (hasta unos 6 MB) y la subida reanudable para los más grandes, que aguanta una conexión móvil inestable. Los videos y los PDF largos subidos desde el celular son donde primero se nota.

Los buckets también pueden restringir formatos. Un bucket que acepta image/png e image/jpeg va a rechazar las fotos de iPhone guardadas como image/heic. Agrega ese formato o convierte las imágenes antes de subirlas.

¿Por qué las imágenes subidas se ven rotas?

Porque el bucket es privado, que es lo correcto por defecto. En Lovable Cloud los buckets nuevos son privados, y los públicos están bloqueados por un ajuste del workspace hasta que un administrador lo desactive. Un archivo privado no tiene enlace público permanente: el código necesita una URL firmada que vence.

const { data } = await supabase.storage.from("documentos").createSignedUrl(ruta, 3600);

Si la app usa getPublicUrl sobre un bucket privado, obtiene una dirección que devuelve error. Haz público un bucket solo si todos sus archivos son para cualquiera en internet, como fotos de productos. La guía de buckets públicos y privados en Supabase te ayuda a decidir.

¿Cómo confirmo que funciona y es seguro?

  1. Sube un archivo como el usuario A. Revisa que aparezca dentro de la carpeta con su ID.
  2. Reemplaza ese archivo como A, para probar el caso de upsert.
  3. Entra como el usuario B e intenta abrir el archivo de A con su ruta. Tiene que fallar.
  4. Cierra sesión e intenta lo mismo. También tiene que fallar.
  5. Sube un archivo grande desde un celular con datos móviles.

El paso 3 es el que todos se saltan, y es el que importa. Si B puede leer los archivos de A, no tienes un problema de subida sino una fuga de datos; mira qué hacer cuando un usuario ve datos de otro.

Respuestas rápidas

¿Por qué en la vista previa sube y a mis usuarios no? Puede que pruebes con una cuenta que la política permite por casualidad, o que la política se agregara después de tus archivos de prueba. Prueba con una cuenta nueva.

¿Hago público el bucket y listo? No. Lo público solo afecta la lectura y deja todos los archivos expuestos. Arregla la política.

¿La exportación de la base incluye los archivos? No. En Lovable Cloud descarga los archivos de storage por separado antes de mover o quitar el backend.

¿Quieres que revisemos tus reglas de storage?

Las políticas de storage son fáciles de dejar casi bien. Si tu app guarda documentos, identificaciones o cualquier cosa privada, conviene que alguien las revise: empieza con el chequeo gratuito de tu app, mira nuestra revisión de seguridad de Supabase y cómo arreglamos apps de Lovable, o escríbenos.

¿Tu app sigue trabada?

Pasa el chequeo gratis con la URL de tu app, o pide la Auditoría de rescate de $299: un ingeniero senior revisa el código y te envía un informe escrito en 2 días hábiles.