synrg 1.1.0 copy "synrg: ^1.1.0" to clipboard
synrg: ^1.1.0 copied to clipboard

A complete Flutter toolkit for Firebase integration, typed data modeling, modular architecture, UI feedback, and scalable app development using BLoC.

🧠 Synrg #

Synrg is a comprehensive Flutter utility package that abstracts and unifies Firebase services, modular state management, data modeling, query building, UI feedback, and validation β€” all with developer experience in mind.

It provides an opinionated architecture for building scalable Flutter apps with:

  • Firebase (Auth, Firestore, Storage, Functions, Remote Config, Realtime DB, Analytics, Crashlytics, Performance)
  • BLoC integration with enhanced state and UI feedback
  • Strongly typed indexing, validation, and serialization logic
  • Production-ready UI modal system
  • 150+ domain-specific validators

✨ Features #

  • βœ… SynrgBlocProvider with automatic modal display and analytics
  • πŸ” Firebase Authentication & profile management
  • πŸ—ƒ Firestore abstraction with SynrgIndexer and paginated querying
  • ⚑ Cloud Functions typed wrapper with result status
  • πŸ“ Firebase Storage simplified upload/download/delete
  • 🌐 Firebase Remote Config wrapper
  • πŸ”„ Realtime Database write, update, listen and delete
  • πŸ“Š Firebase Analytics & Performance tracing
  • πŸ›  Crashlytics error logging and custom attributes
  • πŸ”Ž Query builder (QueryFilter) and parser
  • πŸ“¦ Abstract base class SynrgClass for ID, map, and parent tracking
  • πŸ§ͺ Extensive validation library for IDs, formats, geo, finance, healthcare, etc.

πŸ“¦ Installation #

Add dependency

flutter pub add synrg

Add synrg to your pubspec.yaml:

dependencies:
  synrg: ^latest

Make sure to initialize Firebase in your project.


πŸš€ Getting Started #

import 'package:synrg/synrg.dart';

void main() async {
  await Firebase.initializeApp();

  SynrgCrashlytics.instance.initialize();
  SynrgAuth.initialize(Indexer.profiles);
}

Indexer.profiles is an optional parameter, if the app manages users it will use the passed index to query for the users in formation in sign in, register or update flows.


🧩 Modules #

1. SynrgBlocProvider #

A wrapper over BlocProvider + BlocConsumer that listens for modals and analytics automatically. The listener is there to show messages to the user, using this you can trigger a modal in the ui from the bloc's event code. It also logs the state changes and adds performance metrics

SynrgBlocProvider<MyBloc>(
  bloc: MyBloc()..add(MyInitEvent()),
  builder: (context, state) {
    if (state is MyStateReady) {
      return MyPage();
    }
    return CircularProgressIndicator();
  },
);

Requires states to extend SynrgState:

class MyState extends SynrgState {
  const MyState({this.modal}) : super(modal: modal);
  final SynrgModal? modal;

  @override
  Map<String, dynamic> toMap() => {...};
}

2. SynrgModal #

In BLoC, the logic is located in the events. What this enables is to show the user information from the event logic. Show toasts, dialogs, drawers, etc., based on state.

emit(MyState(modal: SynrgModal(
  message: 'Operation failed',
  level: AlertLevel.error,
  type: SynrgModalType.toast,
)));

3. SynrgAuth #

Firebase Authentication + Profile sync

await SynrgAuth.instance.signIn(email, password);
final user = SynrgAuth.instance.profile;

4. SynrgIndexer<T> #

The indexer is a Firestore helper. Given a model you specify the mapping method and the table name and all the basic interactions are already taken care of.

class Indexer {
  static final profiles = SynrgIndexer<Profile>('profile', Profile.fromMap);
  static final projects = SynrgIndexer<Project>('project', Project.fromMap);
}

final project = await Indexer.projects.get('id123');
await Indexer.projects.save(Project(name: 'New Project'));

Supports pagination, filtering, and batch ops.

5. SynrgFunction<T> #

Cloud Functions with result status: This is similar to the Indexer as it maps the result to the specified output type

class Payments {
  static Future<Profile?> payments({
    required String clientId,
    required int amount,
  }) async {
    final result =
        await SynrgFunction<Profile>('payments', Profile.fromMap).call({
      'clientId': clientId,
      'amount': amount,
    });
    if (result.status == SynrgFunctionStatus.success) {
      return result.result;
    } else {
      throw Exception('Failed to process payment: ${result.status}');
    }
  }
}


final result = await Payments.payments(clientId: 'id', amount: 'abc');

if (result =! null) {
  print(result.name);
}

6. SynrgStorage #

final url = await SynrgStorage.instance.uploadFile('path/file.png', file);
await SynrgStorage.instance.deleteFile('path/file.png');

7. SynrgRealtimeDatabase #

await SynrgRealtimeDatabase.instance.writeData('users/1', {'name': 'Ana'});
final snapshot = await SynrgRealtimeDatabase.instance.readData('users/1');

8. SynrgRemoteConfig #

await SynrgRemoteConfig.instance.initialize();
final showBanner = SynrgRemoteConfig.instance.getBool('show_banner');

9. SynrgCrashlytics #

SynrgCrashlytics.instance.logError(error, stackTrace);
SynrgCrashlytics.instance.setUserIdentifier(userId);

10. SynrgPerformance #

final trace = await SynrgPerformance.instance.startTrace('my-trace');
// ... do work
await SynrgPerformance.instance.stopTrace(trace);

11. SynrgAnalytics #

SynrgAnalytics.instance.logEvent('screen_view', {'page': 'home'});

12. QueryFilter #

Query utilities for SynrgIndexer:

final filters = [
  QueryFilter('status', isEqualTo: 'active'),
  QueryFilter('price', isLessThanOrEqualTo: 100),
];
await index.query(filters);

Supports .toString() and .fromString(...) for dynamic queries.

13. SynrgClass #

Your models should extend SynrgClass for auto-saving and ID handling:

class Project extends SynrgClass {
  final String name;

  Project({required this.name, super.id});

  @override
  Map<String, dynamic> toMap() => {'id': id, 'name': name};

  factory Project.fromMap(Map<String, dynamic> map) =>
      Project(name: map['name'], id: map['id']);
}

πŸ§ͺ Validation #

Import validators from synrg/validators.dart for:

  • πŸ“ Address & Location (zip, city, lat/lng, etc.)
  • πŸ’³ Finance (credit card, CVV, IBAN, etc.)
  • πŸ“† Date & Time (HH:mm:ss, timestamp, etc.)
  • πŸ“¦ Logistics (SKU, barcode, VIN, tracking)
  • 🧬 Healthcare (blood type, allergies, medical IDs)
  • πŸŽ“ Education (student ID, GPA, course code)
  • 🌍 Tech & Network (IPv4/6, MAC, URL, domain, regex, JSON)
  • πŸ“„ Files & Content (file size, extension, CSV, Markdown, etc.)

Example:

TextFormField(
  validator: validateEmailAddress,
)

πŸ”§ Requirements #

  • Flutter 3.16+
  • Firebase (initialized in your app)
  • BLoC (optional but recommended)

🀝 Contributing #

PRs welcome! Please open issues for feedback, bugs or ideas.


πŸ“„ License #

MIT Β© [Your Name or Org]