Supabase en Flutter: ejercicio resuelto con auth y CRUD de tareas
Supabase en Flutter: ejercicio resuelto con auth y CRUD
Supabase es la alternativa open-source a Firebase más usada en 2025-26. Combina base de datos PostgreSQL, autenticación, almacenamiento y funciones edge en un solo servicio. supabase_flutter proporciona un cliente oficial que gestiona sesión, tokens y comunicación con la API de forma reactiva.
Enunciado
Implementa una app de tareas que:
- Permita registro e inicio de sesión con email y contraseña.
- Muestre la pantalla de tareas solo cuando haya sesión activa.
- Cree, complete y elimine tareas en Supabase.
- Aplique Row Level Security para que cada usuario solo vea sus propias tareas.
- Maneje errores de autenticación con mensajes legibles.
Dependencias
Configuración
1. Crear proyecto en Supabase (supabase.com) y copiar la URL y la anon key del panel Settings → API.
2. Crear la tabla tasks en el SQL Editor de Supabase:
3. Inicializar Supabase antes de runApp:
En producción guarda las credenciales con --dart-define o variables de entorno, nunca en el código fuente.
Solución completa
Conceptos clave
| API | Propósito |
|---|---|
Supabase.initialize() | Inicializa el cliente global una vez al arrancar |
supabase.auth.onAuthStateChange | Stream reactivo del estado de sesión |
supabase.auth.signInWithPassword() | Login con email y contraseña |
supabase.auth.signUp() | Registro de nuevo usuario |
supabase.auth.signOut() | Cierra la sesión activa |
supabase.from('tabla').select() | Lee registros (respeta RLS automáticamente) |
supabase.from('tabla').insert({}) | Crea un registro |
supabase.from('tabla').update({}).eq() | Actualiza por condición |
supabase.from('tabla').delete().eq() | Elimina por condición |
AuthException | Error tipado de autenticación (mensaje legible) |
Errores frecuentes
- Credenciales en código fuente: usa
--dart-defineo un gestor de secretos. Laanon keyde Supabase no es un secreto absoluto (está protegida por RLS), pero la URL sí debe controlarse en producción. - Olvidar
awaiten operaciones de escritura:insert,updateydeletesonFuture; sinawaitno verás errores y el estado no se actualizará. - RLS sin política: si activas RLS sin crear políticas, todas las consultas devuelven 0 registros aunque existan datos — el comportamiento es correcto por diseño, pero confunde al no estar documentado.
- No usar
mountedtrasawait: el widget puede haberse desmontado durante la operación asíncrona; compruebamountedantes de llamar asetStateoScaffoldMessenger.
Aplicación práctica
Este patrón es la base de cualquier app con usuarios y datos propios: gestores de notas, CRMs ligeros, apps de seguimiento personal o paneles de administración internos. Supabase añade suscripciones en tiempo real con supabase.from('tasks').stream() cuando necesitas actualizaciones instantáneas sin recargar.
Siguiente ejercicio recomendado
- Secure storage con token en Flutter: ejercicio resuelto
- Auth con refresh token en Flutter: ejercicio resuelto
- Firebase Auth login en Flutter: ejercicio resuelto
- Todos los ejercicios de Flutter
Práctica guiada y siguiente paso
- Más ejercicios de Flutter
- Ejercicios C para reforzar fundamentos
- Programación en C en 100 ejercicios resueltos
- Ver en Amazon (incluido en Kindle Unlimited)
FAQ
¿Supabase es gratis para proyectos pequeños?
Sí. El plan gratuito incluye 500 MB de base de datos, 50.000 usuarios activos al mes y 2 GB de almacenamiento. Es suficiente para MVPs y proyectos personales.
¿Cuál es la diferencia principal con Firebase?
Firebase usa una base de datos NoSQL (Firestore) mientras que Supabase usa PostgreSQL relacional. Supabase es open-source y puede autoalojarse; Firebase es un servicio de Google sin opción de auto-hosting.
¿Cómo protejo la anon key en producción?
La anon key no es un secreto crítico porque el acceso a los datos está controlado por Row Level Security. Lo que sí debes proteger son las operaciones de rol service_role, que nunca deben estar en el cliente.