firestore_wrapper 1.0.3 copy "firestore_wrapper: ^1.0.3" to clipboard
firestore_wrapper: ^1.0.3 copied to clipboard

A type-safe wrapper for Cloud Firestore operations in Flutter, providing a clean and strongly-typed interface.

Firestore Wrapper #

A type-safe wrapper for Cloud Firestore operations in Flutter, providing a clean and strongly-typed interface for working with Firestore data.

Features #

  • 🔒 Type-safe operations - Work with your data models safely
  • 📦 Simplified batch operations - Handle multiple writes atomically
  • 🔄 Transaction helpers - Perform atomic read-write operations
  • 🔍 Query builder - Build complex queries with pagination
  • Real-time updates - Stream data changes in real-time
  • 📝 Clean API - Intuitive interface for Firestore operations

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  firestore_wrapper: ^1.0.0
copied to clipboard

Then run:

flutter pub get
copied to clipboard

Usage #

Define Your Model #

class User {
  final String id;
  final String name;
  final int points;

  User({
    required this.id,
    required this.name,
    required this.points,
  });

  static User fromJson(Map<String, dynamic> json, String id) {
    return User(
      id: id,
      name: json['name'] as String,
      points: json['points'] as int? ?? 0,
    );
  }

  Map<String, dynamic> toJson() => {
    'name': name,
    'points': points,
  };
}
copied to clipboard

Create a Typed Collection #

final usersCollection = Fb.collection<User>(
  'users',
  User.fromJson,
);
copied to clipboard

Basic Operations #

// Create or update a document
final userDoc = usersCollection.doc('123');
await userDoc.set({
  'name': 'John Doe',
  'points': 100,
});

// Get a document
final user = await userDoc.get();
if (user != null) {
  print('User ${user.name} has ${user.points} points');
}

// Update specific fields
await userDoc.update({
  'points': 200,
});

// Delete a document
await userDoc.delete();
copied to clipboard

Queries #

// Build and execute a query
final activeUsers = await usersCollection
  .query()
  .where('status', isEqualTo: 'active')
  .where('points', isGreaterThan: 100)
  .orderBy('points', descending: true)
  .limit(10)
  .get();

// Query with pagination
final result = await usersCollection
  .query()
  .orderBy('createdAt')
  .limit(20)
  .getWithPagination();

final users = result.data;
final lastDoc = result.lastDocument;
copied to clipboard

Real-time Updates #

// Listen to a single document
userDoc.stream().listen((user) {
  if (user != null) {
    print('User updated: ${user.name}');
  }
});

// Listen to query results
usersCollection
  .query()
  .where('status', isEqualTo: 'online')
  .stream()
  .listen((users) {
    print('${users.length} users are online');
  });
copied to clipboard

Batch Operations #

final batch = Fb.batch();

// Queue multiple operations
batch.set('users/123', {
  'status': 'active',
  'lastSeen': FieldValue.serverTimestamp(),
});

batch.update('stats/daily', {
  'activeUsers': FieldValue.increment(1),
});

batch.delete('users/456');

// Commit all operations atomically
await batch.commit();
copied to clipboard

Transactions #

await Fb.runTransaction((transaction) async {
  // Read data
  final senderData = await transaction.get('users/sender123');
  if (senderData == null) throw Exception('Sender not found');
  final senderPoints = senderData['points'] as int? ?? 0;

  final receiverData = await transaction.get('users/receiver456');
  if (receiverData == null) throw Exception('Receiver not found');
  final receiverPoints = receiverData['points'] as int? ?? 0;

  // Perform updates atomically
  transaction.update('users/sender123', {
    'points': senderPoints - 100,
  });
  transaction.update('users/receiver456', {
    'points': receiverPoints + 100,
  });

  return true;
});
copied to clipboard

Additional Features #

Subcollections #

// Get a reference to a user's posts
final userPostsCollection = userDoc.collection<Post>(
  'posts',
  Post.fromJson,
);

// Add a post
final postId = await userPostsCollection.add({
  'title': 'Hello World',
  'content': 'My first post!',
  'createdAt': FieldValue.serverTimestamp(),
});
copied to clipboard

Complex Queries #

final query = usersCollection
  .query()
  .where('tags', arrayContains: 'premium')
  .where('lastSeen', isGreaterThan: DateTime.now().subtract(Duration(days: 7)))
  .orderBy('lastSeen', descending: true)
  .limit(50);

final premiumActiveUsers = await query.get();
copied to clipboard

Error Handling #

The package propagates Firestore errors as-is, allowing you to handle them appropriately:

try {
  await userDoc.update({'points': 100});
} catch (e) {
  if (e is FirebaseException) {
    // Handle specific Firebase errors
    print('Firebase error: ${e.code}');
  } else {
    // Handle other errors
    print('Error: $e');
  }
}
copied to clipboard

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

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

2
likes
160
points
48
downloads

Publisher

unverified uploader

Weekly Downloads

2024.09.26 - 2025.04.10

A type-safe wrapper for Cloud Firestore operations in Flutter, providing a clean and strongly-typed interface.

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

cloud_firestore, firebase_core, flutter

More

Packages that depend on firestore_wrapper