๐Ÿง  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

Libraries

synrg
A Very Good Project created by Very Good CLI.