quicui_supabase 2.0.3 copy "quicui_supabase: ^2.0.3" to clipboard
quicui_supabase: ^2.0.3 copied to clipboard

Supabase implementation for QuicUI framework. Provides backend integration for dynamic UI rendering, real-time synchronization, offline-first architecture, and callback action system support.

QuicUI Supabase Plugin #

Supabase implementation for the QuicUI framework. Enables dynamic UI rendering, real-time synchronization, and offline-first architecture through Supabase cloud infrastructure.

Overview #

The QuicUI Supabase plugin provides a complete backend integration implementing the DataSource interface from QuicUI core. It handles:

  • Screen Management: Fetch, save, search, and delete dynamic UI screens
  • Real-Time Updates: Subscribe to live screen changes via WebSocket
  • Offline Support: Queue operations when offline, auto-sync when reconnected
  • Conflict Resolution: Intelligent handling of concurrent modifications
  • PostgreSQL Backend: Leverage Supabase's PostgreSQL database for data persistence
  • Authentication: Built-in Supabase Auth integration

Installation #

  1. Add to pubspec.yaml:
dependencies:
  quicui_supabase: ^2.0.0
  1. Configure Supabase in your project:
flutter pub add supabase_flutter

Quick Start #

1. Initialize Supabase #

import 'package:supabase_flutter/supabase_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Supabase.initialize(
    url: 'https://your-project.supabase.co',
    anonKey: 'your-anon-key',
  );

  runApp(const MyApp());
}

2. Register DataSource #

import 'package:quicui/quicui.dart';
import 'package:quicui_supabase/quicui_supabase.dart';

void setupQuicUI() async {
  final dataSource = SupabaseDataSource(
    supabaseUrl: 'https://your-project.supabase.co',
    supabaseAnonKey: 'your-anon-key',
  );

  DataSourceProvider.instance.register(dataSource);
  await dataSource.connect();
}

3. Use with QuicUI #

final repository = ScreenRepository(
  dataSource: DataSourceProvider.instance.get(),
);

final screen = await repository.getScreen('home_screen');
final renderer = UIRenderer();
final widget = renderer.renderScreen(screen);

4. Complete Cloud Backend Example #

Here's a complete example using Supabase as a cloud backend for dynamic UI:

import 'package:flutter/material.dart';
import 'package:quicui/quicui.dart';
import 'package:quicui_supabase/quicui_supabase.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Initialize Supabase first
  await Supabase.initialize(
    url: 'https://your-project.supabase.co',
    anonKey: 'your-anon-key',
  );
  
  // Initialize with backend (optional)
  final dataSource = SupabaseDataSource(
    'https://your-project.supabase.co',
    'your-anon-key',
  );
  await QuicUIService().initializeWithDataSource(dataSource);
  
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // Now fetch dynamic UI from backend
    return MaterialApp(
      title: 'QuicUI with Supabase',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: FutureBuilder<Screen>(
        future: QuicUIService().fetchScreen('home_screen'),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Scaffold(
              body: Center(child: CircularProgressIndicator()),
            );
          }
          
          if (snapshot.hasError) {
            return Scaffold(
              appBar: AppBar(title: const Text('Error')),
              body: Center(child: Text('Error: ${snapshot.error}')),
            );
          }
          
          if (snapshot.hasData) {
            final screen = snapshot.data!;
            return UIRenderer().renderScreen(screen);
          }
          
          return const Scaffold(
            body: Center(child: Text('No screen found')),
          );
        },
      ),
    );
  }
}

This example:

  • ✅ Initializes Supabase with your credentials
  • ✅ Sets up QuicUI with the Supabase backend plugin
  • ✅ Fetches the 'home_screen' from your Supabase database
  • ✅ Renders the dynamic UI from JSON
  • ✅ Handles loading, error, and success states

For more examples, see the QuicUI main package documentation.

Usage Examples #

Fetch Screens #

final dataSource = DataSourceProvider.instance.get();

// Get single screen
final screen = await dataSource.fetchScreen('home_screen');

// Get multiple screens with pagination
final screens = await dataSource.fetchScreens(limit: 20, offset: 0);

// Search screens
final results = await dataSource.searchScreens('dashboard');

// Get total count
final count = await dataSource.getScreenCount();

Save/Update Screens #

final screen = Screen(
  id: 'new_screen',
  name: 'New Screen',
  version: 1,
  rootWidget: WidgetData(...),
  metadata: null,
  createdAt: DateTime.now(),
  updatedAt: DateTime.now(),
  isActive: true,
  config: const ScreenConfig(),
);

await dataSource.saveScreen('new_screen', screen);

Real-Time Updates #

final stream = dataSource.subscribeToScreen('home_screen');

stream.listen((event) {
  print('Event type: ${event.type}'); // insert, update, delete
  print('Data: ${event.data.id}');
  print('Timestamp: ${event.timestamp}');
});

// Unsubscribe when done
await dataSource.unsubscribe('home_screen');

Handle Offline Scenarios #

// Get pending items that failed to sync
final pendingItems = await dataSource.getPendingItems();

// Attempt to sync
final syncResult = await dataSource.syncData(pendingItems);

print('Synced: ${syncResult.synced}');
print('Failed: ${syncResult.failed}');

// Check specific errors
for (final error in syncResult.errors) {
  print('Failed to ${error.operation}: ${error.error}');
}

Error Handling #

import 'package:quicui_supabase/quicui_supabase.dart';

try {
  final screen = await dataSource.fetchScreen('missing');
} on ScreenNotFoundException catch (e) {
  print('Screen not found: ${e.message}');
} on SupabaseDataSourceException catch (e) {
  print('Supabase error: ${e.message}');
} on DataSourceException catch (e) {
  print('Backend error: ${e.message}');
}

Database Schema #

The plugin expects the following Supabase tables:

screens table #

create table screens (
  id text primary key,
  name text not null,
  version integer not null default 1,
  root_widget jsonb not null,
  metadata jsonb,
  config jsonb,
  is_active boolean default true,
  created_at timestamp with time zone default now(),
  updated_at timestamp with time zone default now()
);

-- Create index for search
create index screens_name_search on screens using gin(name gin_trgm_ops);

sync_queue table #

create table sync_queue (
  id uuid primary key default gen_random_uuid(),
  screen_id text not null,
  operation text not null,
  screen_data jsonb,
  synced boolean default false,
  retry_count integer default 0,
  last_error text,
  created_at timestamp with time zone default now(),
  updated_at timestamp with time zone default now()
);

Enable Real-Time (Supabase UI) #

  1. Go to Database → Replication
  2. Enable real-time on screens table
  3. Enable UPDATE, INSERT, DELETE events

Architecture #

QuicUI App
  ↓
ScreenRepository
  ↓
DataSourceProvider (Service Locator)
  ↓
SupabaseDataSource (This Plugin)
  ↓
Supabase Backend
  ├─ PostgreSQL (screens, sync_queue tables)
  ├─ Real-Time (WebSocket subscriptions)
  └─ Auth (User authentication)

Features #

Screen Management #

  • fetchScreen(screenId) - Get single screen
  • fetchScreens(limit, offset) - Paginated list
  • saveScreen(screenId, screen) - Create/update
  • deleteScreen(screenId) - Delete screen
  • searchScreens(query) - Full-text search
  • getScreenCount() - Total screen count

Real-Time Synchronization #

  • subscribeToScreen(screenId) - Stream updates
  • unsubscribe(screenId) - Stop listening
  • ✅ WebSocket connections
  • ✅ Automatic reconnection

Offline Support #

  • getPendingItems() - Get queued operations
  • syncData(items) - Batch sync
  • resolveConflict(conflict) - Conflict resolution

Connection Management #

  • connect() - Initialize connection
  • disconnect() - Cleanup
  • isConnected() - Check status

Testing #

Run tests with:

cd quicui_supabase
flutter test

Troubleshooting #

Connection Issues #

try {
  await dataSource.connect();
} on SupabaseDataSourceException catch (e) {
  print('Connection failed: ${e.message}');
  print('Cause: ${e.originalError}');
}

Real-Time Not Working #

  1. Verify real-time is enabled on screens table
  2. Check WebSocket connection in browser DevTools
  3. Ensure Supabase URL and key are correct
  4. Check Supabase project status/logs

Sync Failures #

final result = await dataSource.syncData(pendingItems);
for (final error in result.errors) {
  print('${error.itemId}: ${error.error}');
}

Performance Tips #

  • Use pagination: fetchScreens(limit: 20, offset: 0)
  • Debounce search: searchScreens(query) can be expensive
  • Subscribe only to needed screens
  • Call disconnect() when app closes
  • Use isConnected() to check before operations

Migration from Direct Supabase #

If you're currently using Supabase directly in QuicUI:

// Before
final supabaseService = SupabaseService(...);
final screen = await supabaseService.getScreen('home');

// After
final dataSource = SupabaseDataSource(...);
DataSourceProvider.instance.register(dataSource);
final repository = ScreenRepository(dataSource: dataSource);
final screen = await repository.getScreen('home_screen');

API Reference #

See lib/src/supabase_data_source.dart for detailed API documentation.

Support #

License #

MIT License - See LICENSE file for details.


❤️ Love QuicUI? #

If you're enjoying QuicUI and the Supabase plugin, consider supporting the development!

🚀 Why Support QuicUI? #

  • 📚 Comprehensive documentation and guides
  • �� Fast bug fixes and issue resolution
  • 💡 New features and improvements based on community feedback
  • 📞 Dedicated support and guidance
  • 🎯 Long-term project sustainability

Buy Me a Coffee #

Your support helps keep QuicUI thriving and enables faster development of new features!

Buy Me a Coffee

Thank you for being part of the QuicUI community! 🙏

0
likes
95
points
10
downloads

Publisher

verified publisherdowonder.in

Weekly Downloads

Supabase implementation for QuicUI framework. Provides backend integration for dynamic UI rendering, real-time synchronization, offline-first architecture, and callback action system support.

Repository (GitHub)
View/report issues

Documentation

Documentation
API reference

License

unknown (license)

Dependencies

equatable, flutter, logger, quicui, supabase_flutter

More

Packages that depend on quicui_supabase