Upload Images in Flutter to Supabase Storage: The Complete Guide

Upload images from Flutter to Supabase Storage the right way — buckets, RLS policies, image_picker, public vs signed URLs, and on-the-fly image transformations with complete Dart code.

Every app eventually needs file uploads — profile pictures, chat attachments, post images. Supabase Storage gives you an S3-compatible object store with Row Level Security on top, and supabase_flutter makes the client side a handful of lines. The part that actually trips people up isn't the upload call — it's the storage policies . Get those wrong and every upload fails with a cryptic 403. This guide covers the full flow: creating a bucket, writing correct storage.objects RLS policies, picking an image, uploading it, and serving it back via public or signed URLs — plus on-the-fly image transformations. Written against supabase_flutter v2 (stable) and Flutter 3.47 / Dart 3.13 . What you'll build A public avatars bucket with proper RLS Image picking with image_picker Upload with progress-friendly error handling Public URLs, signed URLs (for private buckets), and resized thumbnails Step 1 — Create the bucket Dashboard → Storage → New bucket. Name it avatars . You'll face one decision: Public bucket — anyone with the URL can read. Right for avatars, post images, product photos. Private bucket — reads need a signed URL. Right for invoices, medical records, anything sensitive. We'll build the public case first, then cover private buckets with signed URLs. Step 2 — Write the storage RLS policies (don't skip this) Storage uses the storage.objects table for policies, and bucket_id tells you which bucket a row belongs to. New buckets deny everything by default — that's why fresh projects get "new row violates row-level security policy" on the first upload. Run this in the SQL editor. It lets any authenticated user upload to their own folder (path = <user-id>/avatar.png ), and lets everyone read: -- Everyone can view avatars (public bucket) create policy "Public read access" on…

Explore