Setting up Flutter ODM with Firestore and Freezed
Generate types for your firebase collections
One of firestores nicest features is also one of its weakest… its schemaless. If you have multiple developers working on the same project you might run into issues where your docs may have values you were expecting or that are incorrect. You can use Freezed with Firestore to generate types for your flutter project that when then allow things such as autocompletion to happen as well as give every develop an easy place to look at to see the structure of a collection
In order to do this we need a few packages
flutter pub add cloud_firestore_odm freezed json_annotation cloud_firestore_odm freezed_annotation build_runner json_serializable
Here’s a sample type for us. We’re going to call this chore
// ignore_for_file: invalid_annotation_target, avoid-dynamic
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cloud_firestore_odm/cloud_firestore_odm.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'notification.freezed.dart';
part 'notification.g.dart';
<Notification>('notifications')
class Notification with _$Notification {
()
factory Notification(
{required NotificationBody notification,
NotificationData? data,
required List<String> recipientIds}) = _Notification;
factory Notification.fromJson(Map<String, Object?> json) =>
_$NotificationFromJson(json);
}
class NotificationBody with _$NotificationBody {
()
factory NotificationBody({required String? title, required String? body}) =
_NotificationBody;
factory NotificationBody.fromJson(Map<String, Object?> json) =>
_$NotificationBodyFromJson(json);
}
class NotificationData with _$NotificationData {
()
factory NotificationData({required String? path, required String? extra}) =
_NotificationData;
factory NotificationData.fromJson(Map<String, Object?> json) =>
_$NotificationDataFromJson(json);
}
final notificationsRef = NotificationCollectionReference();
Anyone in your application you can import this file and it will give you the ability to perform CRUD operations on this collection. Heres a simple class where I import our generated model with final NotificationCollectionReference _notificationsRef;
and then create a new document
class NotificationRepository {
NotificationRepository(this._notificationsRef);
final NotificationCollectionReference _notificationsRef;
void createTestPushNotification() async {
if (FirebaseAuth.instance.currentUser?.uid != null) {
await _notificationsRef.doc().set(Notification(
notification: NotificationBody(
title: 'Test - ${randomNumeric(3)}', body: randomString(15)),
recipientIds: [
FirebaseAuth.instance.currentUser!.uid
]));
}
}
}