firestore_core_plus library

Firebase Core Plus - A Flutter package for type-safe Firestore operations.

This package extends Firebase Core with strong typing and serialization capabilities for Firestore operations. It provides a clean, type-safe API for working with Firestore collections and documents.

Main Components

  • InterfacePlus: Abstract interface that enforces consistent model structure
  • FirestorePlus: Generic class for type-safe Firestore operations

Quick Start

import 'package:firebase_core_plus/firebase_core_plus.dart';

// 1. Create your model implementing InterfacePlus
class User implements InterfacePlus {
  User({required this.uid, required this.name, required this.email});

  @override
  String? uid;
  final String name;
  final String email;

  @override
  Map<String, dynamic> get json => {
    'uid': uid,
    'name': name,
    'email': email,
  };

  static User withMap(Map<String, dynamic> map) => User(
    uid: map['uid'],
    name: map['name'],
    email: map['email'],
  );
}

// 2. Create FirestorePlus instance
final userCollection = FirestorePlus<User>.instance(
  tConstructor: User.withMap,
  path: 'users',
);

// 3. Use type-safe operations
final user = User(uid: '', name: 'John Doe', email: 'john@example.com');
final userId = await userCollection.add(object: user);

// 4. Real-time streams
StreamBuilder<List<User>>(
  stream: userCollection.streams,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      final users = snapshot.data!;
      return ListView.builder(
        itemCount: users.length,
        itemBuilder: (context, index) => Text(users[index].name),
      );
    }
    return CircularProgressIndicator();
  },
);

Key Features

Type Safety

  • All operations are type-safe through Dart generics
  • Compile-time checking prevents runtime errors
  • Automatic serialization/deserialization

Real-time Updates

  • Stream-based API for live data updates
  • Automatic UI updates when data changes
  • Efficient resource management

CRUD Operations

  • Create, Read, Update, Delete operations
  • Batch operations support
  • Error handling and validation

Search Capabilities

  • Single and multi-field search
  • Real-time search streams
  • Optimized Firestore queries

Sub-collections

  • Type-safe sub-collection access
  • Nested data structure support
  • Complex relationship handling

Architecture

The package follows a clean architecture pattern:

InterfacePlus (Abstract Interface)
    ↓
FirestorePlus<T> (Generic Implementation)
    ↓
Firestore (Underlying Database)

InterfacePlus

  • Enforces consistent model structure
  • Provides serialization contract
  • Ensures type safety across the application

FirestorePlus

  • Generic wrapper around Firestore operations
  • Type-safe CRUD operations
  • Stream and Future APIs
  • Search and filtering capabilities

Best Practices

Model Design

  1. Always implement InterfacePlus in your models
  2. Use meaningful property names
  3. Handle type casting safely in withMap
  4. Add business logic methods to your models
  5. Use consistent field names across your schema

Performance

  1. Use appropriate limits for large collections
  2. Consider using futures for one-time data fetching
  3. Implement proper error handling
  4. Use indexes for frequently searched fields
  5. Avoid deeply nested sub-collections

Error Handling

  1. Always wrap operations in try-catch blocks
  2. Provide meaningful error messages
  3. Handle network connectivity issues
  4. Validate data before saving
  5. Use proper logging for debugging

Migration from Raw Firestore

If you're migrating from raw Firestore operations, here's how to convert:

Before (Raw Firestore)

// Adding a document
await FirebaseFirestore.instance
  .collection('users')
  .add({
    'name': 'John Doe',
    'email': 'john@example.com',
  });

// Getting documents
final snapshot = await FirebaseFirestore.instance
  .collection('users')
  .get();
final users = snapshot.docs.map((doc) {
  final data = doc.data();
  return User(
    uid: doc.id,
    name: data['name'],
    email: data['email'],
  );
}).toList();

After (FirestorePlus)

// Adding a document
final user = User(uid: '', name: 'John Doe', email: 'john@example.com');
final userId = await userCollection.add(object: user);

// Getting documents
final users = await userCollection.futures;

Examples

See the example/ directory for complete Flutter applications demonstrating:

  • Basic CRUD operations
  • Real-time streams
  • Search functionality
  • Sub-collection usage
  • Error handling
  • Modern UI implementation

Contributing

Contributions are welcome! Please see the contributing guidelines for:

  • Code style and formatting
  • Testing requirements
  • Documentation standards
  • Pull request process

License

This project is licensed under the MIT License - see the LICENSE file for details.

Classes

FirestorePlus<T>
A generic class that provides type-safe Firestore operations.
InterfacePlus
Abstract interface that enforces consistent model structure for Firestore operations.