Recommended patterns and practices for using the Supabase plugin in Unreal Engine Blueprints.
All database, auth, and storage operations are asynchronous. Always follow this pattern:
1. Create the async node (e.g., "Fetch Rows Async")
2. Set input parameters (table name, filters, etc.)
3. Bind the "On Success" and "On Error" delegates
4. Call "Activate()"
Never call Activate() before binding delegates, or you may miss callbacks.
┌─────────────────────────┐
│ Begin Object │
│ → Fetch Rows Async │
│ Table: "players" │
│ → On Success │──→ Process Data
│ → On Error │──→ Log Error
│ → Activate() │
└─────────────────────────┘
Always bind the On Error delegate. Unhandled errors can cause silent failures.
Create a Blueprint Function Library or custom event for error handling:
Event HandleSupabaseError(String ErrorMessage)
├── Log Error (ErrorMessage)
├── Show UI Notification ("Operation failed")
└── Optionally retry or fall back
1. Game Start → USupabaseSubsystem auto-initializes
2. Wait for connection (use "Test Connection Async")
3. Once connected → proceed with auth/data operations
Event OnGameReady
├── Test Connection Async
│ → On Success: Set "bIsConnected" = true
│ → On Error: Retry after delay
└── Only run data operations when bIsConnected = true
1. Check for saved session (USupabaseSessionSave)
2. If session exists → try Refresh Session Async
3. If refresh fails or no session → show login UI
4. On successful login → Save Session Async
5. On logout → Clear Authentication Data
1. Validate Email Format
2. Validate Password Strength
3. If both valid → Register With Options Async
4. Handle email confirmation if required
Instead of fetching all rows and filtering client-side, use UQueryFilter:
QueryFilter = Create QueryFilter
QueryFilter.AddFilter("score", GreaterThan, "100")
QueryFilter.AddFilter("level", Equals, "5")
QueryFilter.SetLimitFilter(50)
QueryFilter.SetSortFilter("score", Descending)
→ Fetch Rows Async (Table: "players", Filter: QueryFilter)
Use existence checks to avoid duplicate entries:
Does Row Exist With Filter Async (Table: "profiles", Filter: "user_id = current_user_id")
├── On Success (exists) → Update Row Async
└── On Success (not exists) → Insert Row Async
When you're unsure whether a row exists, use Upsert Row Async instead of separate insert/update logic.
For files larger than 5MB, use upload options with chunking enabled:
UploadOptions.bUseChunkedUpload = true
UploadOptions.ChunkSize = 1MB
UploadOptions.bReportProgress = true
UploadOptions.MaxFileSize = 50MB
Upload File With Options Async (Bucket, Path, UploadOptions)
├── On Upload Progress → Update UI progress bar
└── On Success → File uploaded
Upload File With Options Async
├── Cancel Button → Cancel Upload
├── Pause Button → Pause Upload
└── Resume Button → Resume Upload
For production use, prefer Subscribe To Realtime Advanced Async over the basic version:
Subscribe To Realtime Advanced Async
├── EventTypes: ["INSERT", "UPDATE", "DELETE"]
├── HeartbeatInterval: 30.0
├── bEnableReconnection: true
├── MaxReconnectAttempts: 5
└── Schema: "public"
Periodically check Is Connection Healthy and handle reconnection:
Every 60 seconds:
├── Is Connection Healthy?
│ ├── true → Continue
│ └── false → Reconnect
EntityPersistence Config:
├── bAutoSave: true
├── bAutoLoad: true
├── bSaveOnDestroy: true
├── AutoSaveInterval: 300.0 (5 minutes)
└── ValidateData: true
Always use validation to prevent corrupt data:
Validate Current Data
├── On Valid → Save Data Async
└── On Invalid → Fix data or log error
Fetch Rows Async with a limit instead of multiple single fetchesUQueryFilterSet the log verbosity for the Supabase module:
Log LogSupabase:Verbose
Print String nodes on async callbacks to verify data flowOn Error delegate to catch and display API errorsVersion: 1.4.1 | Last Updated: May 2026