supa_helper 0.0.1 copy "supa_helper: ^0.0.1" to clipboard
supa_helper: ^0.0.1 copied to clipboard

A clean and simple wrapper around Supabase for Flutter projects.

supa_helper #

A Flutter package that provides a clean, simplified wrapper around Supabase services — authentication, database, storage, and realtime — through a single singleton interface.


Features #

  • 🔐 Authentication — Email/password, social sign-in (Google, Apple, Facebook), and phone OTP
  • 🗄️ Database — Simple CRUD helpers (GET, INSERT, UPDATE, DELETE, UPSERT, RPC, COUNT)
  • 📦 Storage — Upload, download, delete, move, copy files and manage buckets
  • 📡 Realtime — Subscribe to Postgres table changes with named channels
  • Lazy initialization — Services are only created when first accessed
  • 🧱 Typed exceptions — Each service throws its own SupaException subclass

Installation #

Add the dependency to your pubspec.yaml:

dependencies:
  supa_helper:
    path: ../supa_helper   # or your pub.dev / git reference

Then run:

flutter pub get

Setup #

Initialize once at app startup, typically in main.dart:

import 'package:supa_helper/supa_helper.dart';

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

  await supa.init(
    url: 'YOUR_SUPABASE_URL',
    anonKey: 'YOUR_SUPABASE_ANON_KEY',
  );

  runApp(const MyApp());
}

Authentication #

Email & Password #

// Sign in
final response = await supa.auth.signInWithEmailAndPassword(
  email: 'user@example.com',
  password: 'password123',
);

// Register
final response = await supa.auth.createUser(
  email: 'user@example.com',
  password: 'password123',
  metaData: {'name': 'John Doe'},
);

// Forgot password
await supa.auth.sendForgetPasswordEmail(email: 'user@example.com');

// Update user
await supa.auth.updateUser(password: 'newPassword');

Social Sign-In #

// Google
final response = await supa.auth.socialMediaSignIn<GoogleSignInAuthentication>(
  SupaGoogleProvider(serverClientId: 'YOUR_SERVER_CLIENT_ID'),
  (googleAuth) => print('Google raw data: $googleAuth'),
);

// Apple
final response = await supa.auth.socialMediaSignIn<AuthorizationCredentialAppleID>(
  SupaAppleProvider(),
  (appleCred) => print('Apple raw data: $appleCred'),
);

// Facebook
final response = await supa.auth.socialMediaSignIn<LoginResult>(
  SupaFacebookProvider(),
  (fbResult) => print('Facebook raw data: $fbResult'),
);

For Facebook, follow the setup guide at https://facebook.meedu.app/docs/7.x.x/intro/

Phone OTP #

// Send OTP
await supa.auth.phoneProvider.sendOtp(phone: '+1234567890');

// Verify OTP
final response = await supa.auth.phoneProvider.verifyOtp(
  phone: '+1234567890',
  otp: '123456',
);

Database #

All methods map directly to common Supabase PostgREST operations.

// Fetch multiple rows
final users = await supa.database.GET(
  table: 'users',
  filter: (q) => q.eq('active', true).order('created_at'),
);

// Fetch a single row
final user = await supa.database.GET_SINGLE(
  table: 'users',
  filter: (q) => q.eq('id', userId),
);

// Insert
final newUser = await supa.database.INSERT(
  table: 'users',
  data: {'name': 'Jane', 'email': 'jane@example.com'},
);

// Insert many
final rows = await supa.database.INSERT_MANY(
  table: 'products',
  data: [{'name': 'A'}, {'name': 'B'}],
);

// Upsert
await supa.database.UPSERT(
  table: 'profiles',
  data: {'id': userId, 'bio': 'Hello!'},
);

// Update
await supa.database.UPDATE(
  table: 'users',
  data: {'name': 'Updated Name'},
  column: 'id',
  value: userId,
);

// Delete
await supa.database.DELETE(
  table: 'users',
  column: 'id',
  value: userId,
);

// Call a Postgres function
final result = await supa.database.RPC(
  function: 'my_function',
  params: {'param1': 'value'},
);

// Count rows
final count = await supa.database.COUNT(
  table: 'orders',
  filter: (q) => q.eq('status', 'pending'),
);

Storage #

import 'dart:io';

// Upload a File and get its public URL
final url = await supa.storage.uploadAndGetUrl(
  File('/path/to/image.jpg'),
  bucketName: 'avatars',
  folderName: 'users',
  prefix: 'AVATAR',
);

// Upload raw bytes
final url = await supa.storage.uploadBytesAndGetUrl(
  bytes,
  bucketName: 'documents',
  folderName: 'reports',
  mimeType: 'application/pdf',
);

// Download a file
final bytes = await supa.storage.downloadFile(
  bucketName: 'avatars',
  filePath: 'users/AVATAR123456',
);

// Download directly to a File
await supa.storage.downloadToFile(
  bucketName: 'avatars',
  filePath: 'users/AVATAR123456',
  destination: File('/local/path/file.jpg'),
);

// Get public URL
final url = supa.storage.getPublicUrl(
  bucketName: 'avatars',
  filePath: 'users/AVATAR123456',
);

// Create a signed (temporary) URL
final signedUrl = await supa.storage.createSignedUrl(
  bucketName: 'documents',
  filePath: 'reports/report.pdf',
  expiresInSeconds: 3600,
);

// Delete a file
await supa.storage.deleteFile(
  bucketName: 'avatars',
  filePath: 'users/AVATAR123456',
);

// Delete multiple files
await supa.storage.deleteFiles(
  bucketName: 'avatars',
  filePaths: ['users/A', 'users/B'],
);

// Move / copy
await supa.storage.moveFile(bucketName: 'docs', fromPath: 'a/file', toPath: 'b/file');
await supa.storage.copyFile(bucketName: 'docs', fromPath: 'a/file', toPath: 'b/file');

// List files in a folder
final files = await supa.storage.listFiles(
  bucketName: 'avatars',
  folderPath: 'users',
);

// Bucket management
await supa.storage.createBucket('my-bucket', isPublic: true);
await supa.storage.emptyBucket('my-bucket');
await supa.storage.deleteBucket('my-bucket');
final buckets = await supa.storage.listBuckets();

Realtime #

// Subscribe to all changes on a table
supa.realtime.subscribeToTable(
  channelName: 'orders-channel',
  schema: 'public',
  table: 'orders',
  callback: (payload) => print('Change: ${payload.newRecord}'),
  onError: (e) => print('Error: $e'),
);

// Subscribe to a specific row
supa.realtime.subscribeToTable(
  channelName: 'my-order',
  schema: 'public',
  table: 'orders',
  event: PostgresChangeEvent.update,
  filter: PostgresChangeFilter(
    type: PostgresChangeFilterType.eq,
    column: 'id',
    value: orderId,
  ),
  callback: (payload) => print('Updated: ${payload.newRecord}'),
);

// Unsubscribe a single channel
supa.realtime.unsubscribe('orders-channel');

// Unsubscribe all
supa.realtime.unsubscribeAll();

// Check subscription status
final isActive = supa.realtime.isSubscribed('orders-channel');
final count = supa.realtime.activeChannelsCount;

Error Handling #

Every service throws a typed subclass of SupaException:

Exception Thrown by
SupaAuthException supa.auth
SupaDatabaseException supa.database
SupaStorageException supa.storage
SupaRealtimeException supa.realtime
try {
  await supa.auth.signInWithEmailAndPassword(
    email: 'user@example.com',
    password: 'wrong',
  );
} on SupaAuthException catch (e) {
  print('Auth error: ${e.message}');
} on SupaException catch (e) {
  print('Supa error: ${e.message}');
}

Custom Social Provider #

Implement SupaSocialMediaAuth<T> to add your own OAuth provider:

class MyCustomProvider implements SupaSocialMediaAuth<MyCredential> {
  @override
  OAuthProvider get oAuthProvider => OAuthProvider.github;

  @override
  Future<SupaAuthResult<MyCredential>> signIn() async {
    // your sign-in logic
    return SupaAuthResult(idToken: 'token', rawData: myCredential);
  }
}

Reset / Logout #

Call supa.reset() after sign-out to clear all cached service instances:

await supabase.auth.signOut();
supa.reset();

License #

MIT

7
likes
0
points
118
downloads

Publisher

unverified uploader

Weekly Downloads

A clean and simple wrapper around Supabase for Flutter projects.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_facebook_auth, google_sign_in, sign_in_with_apple, supabase_flutter

More

Packages that depend on supa_helper