TechLead
Lección 5 de 8
5 min de lectura
Supabase

Supabase Storage

Almacena y sirve archivos con buckets y políticas de Supabase Storage

Supabase Storage

Supabase Storage te permite almacenar y servir archivos como imágenes, videos y documentos. Está construido sobre almacenamiento de objetos compatible con S3, con CDN integrada, y se integra con Supabase Auth para un control de acceso seguro.

📁 Funciones de Storage

  • Buckets: Organiza archivos en contenedores
  • Policies: Control de acceso con reglas tipo RLS
  • CDN: Red global de entrega de contenido
  • Transformations: Redimensionar y optimizar imágenes

Crear buckets

Crea buckets en el Dashboard o vía SQL:

-- Create a public bucket
INSERT INTO storage.buckets (id, name, public)
VALUES ('avatars', 'avatars', true);

-- Create a private bucket
INSERT INTO storage.buckets (id, name, public)
VALUES ('documents', 'documents', false);

Subir archivos

// Upload a file
const { data, error } = await supabase.storage
  .from('avatars')
  .upload('user-123/avatar.png', file, {
    cacheControl: '3600',
    upsert: false
  })

// Upload with custom content type
const { data, error } = await supabase.storage
  .from('documents')
  .upload('report.pdf', file, {
    contentType: 'application/pdf'
  })

Subida de archivos en React

function FileUpload() {
  const handleUpload = async (e) => {
    const file = e.target.files[0]
    const fileExt = file.name.split('.').pop()
    const fileName = `${Date.now()}.${fileExt}`

    const { data, error } = await supabase.storage
      .from('uploads')
      .upload(fileName, file)

    if (error) {
      console.error('Upload error:', error)
    } else {
      console.log('Uploaded:', data.path)
    }
  }

  return 
}

Descargar archivos

// Download file as blob
const { data, error } = await supabase.storage
  .from('documents')
  .download('report.pdf')

// Get public URL (for public buckets)
const { data } = supabase.storage
  .from('avatars')
  .getPublicUrl('user-123/avatar.png')

console.log(data.publicUrl)

// Get signed URL (for private buckets)
const { data, error } = await supabase.storage
  .from('documents')
  .createSignedUrl('report.pdf', 3600) // expires in 1 hour

Listar archivos

// List files in a folder
const { data, error } = await supabase.storage
  .from('uploads')
  .list('user-123', {
    limit: 100,
    offset: 0,
    sortBy: { column: 'created_at', order: 'desc' }
  })

Eliminar archivos

// Delete a single file
const { error } = await supabase.storage
  .from('uploads')
  .remove(['user-123/old-file.png'])

// Delete multiple files
const { error } = await supabase.storage
  .from('uploads')
  .remove(['file1.png', 'file2.png', 'file3.png'])

Políticas de Storage

Controla el acceso a tus archivos con políticas de almacenamiento:

-- Allow authenticated users to upload to their folder
CREATE POLICY "Users can upload own files"
ON storage.objects FOR INSERT
TO authenticated
WITH CHECK (
  bucket_id = 'uploads' AND
  (storage.foldername(name))[1] = auth.uid()::text
);

-- Allow users to read their own files
CREATE POLICY "Users can read own files"
ON storage.objects FOR SELECT
TO authenticated
USING (
  bucket_id = 'uploads' AND
  (storage.foldername(name))[1] = auth.uid()::text
);

-- Allow anyone to read public avatars
CREATE POLICY "Public avatar access"
ON storage.objects FOR SELECT
TO anon, authenticated
USING (bucket_id = 'avatars');

Transformaciones de imágenes

// Get resized image URL
const { data } = supabase.storage
  .from('avatars')
  .getPublicUrl('user-123/avatar.png', {
    transform: {
      width: 200,
      height: 200,
      resize: 'cover'
    }
  })

💡 Puntos clave

  • • Usa buckets para organizar archivos por tipo o nivel de acceso
  • • Los buckets públicos permiten acceso directo por URL
  • • Los buckets privados requieren URLs firmadas
  • • Las políticas de Storage funcionan como RLS para archivos
  • • Las transformaciones de imágenes ocurren en el edge de la CDN

📚 Más recursos

Continuar Aprendiendo