| name | json_converter_helper-converters |
| description | Use when defining Freezed and json_serializable models that interact with Cloud Firestore types such as Timestamp, DocumentReference, Color, and UnionTimestamp using json_converter_helper. |
json_converter_helper Converters Guide
json_converter_helper provides standard, battle-tested JsonConverter implementations for json_serializable and freezed models, specializing in Cloud Firestore data types (such as Timestamp, DocumentReference, Color, and UnionTimestamp).
Guidelines
- Standard Global Converters:
- Prefer annotating your model class with
@allJsonConvertersSerializable or specifying converters: allJsonConverters on @JsonSerializable to automatically register all common Firestore converters.
- Handling Firestore Timestamps (
UnionTimestamp):
- Use
UnionTimestamp instead of raw DateTime? or Timestamp? when models need to generate FieldValue.serverTimestamp() on document creation or update.
- On write,
UnionTimestamp.serverTimestamp() serializes to FieldValue.serverTimestamp().
- On read,
UnionTimestamp.dateTime(date) deserializes the incoming Firestore Timestamp into a Dart DateTime.
- To ensure server timestamp generation on updates, use
UnionTimestampConverter.alwaysServerTimestampConverter or pass alwaysServerTimestampJson: true.
- Individual Converters:
@timestampConverter: Converts Firestore Timestamp <-> Dart DateTime.
@documentReferenceConverter: Serializes DocumentReference to JSON path/reference safely.
@colorConverter: Serializes Flutter Color <-> int value.
Examples
1. Freezed Model with @allJsonConvertersSerializable
import 'dart:ui';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:json_converter_helper/json_converter_helper.dart';
part 'user_profile.freezed.dart';
part 'user_profile.g.dart';
@freezed
abstract class UserProfile with _$UserProfile {
@allJsonConvertersSerializable
const factory UserProfile({
required String id,
required String name,
required Color themeColor,
required UnionTimestamp createdAt,
@UnionTimestampConverter.alwaysServerTimestampConverter
required UnionTimestamp updatedAt,
DocumentReference<Map<String, dynamic>>? organizationRef,
}) = _UserProfile;
factory UserProfile.fromJson(Map<String, dynamic> json) =>
_$UserProfileFromJson(json);
}
2. Creating Documents with UnionTimestamp
final profile = UserProfile(
id: 'user_123',
name: 'Mono',
themeColor: const Color(0xFF4285F4),
createdAt: const UnionTimestamp.serverTimestamp(),
updatedAt: const UnionTimestamp.serverTimestamp(),
);
// Serialized map correctly contains FieldValue.serverTimestamp() for createdAt & updatedAt
await FirebaseFirestore.instance
.collection('users')
.doc(profile.id)
.set(profile.toJson());
3. Reading and Displaying DateTime
final snapshot = await FirebaseFirestore.instance
.collection('users')
.doc('user_123')
.get();
final user = UserProfile.fromJson(snapshot.data()!);
// Access date directly via union mapping or .date property
final createdDate = user.createdAt.map(
dateTime: (d) => d.date,
serverTimestamp: (_) => DateTime.now(), // Fallback if pending local write
);
print('Created at: $createdDate');
Common Pitfalls & Anti-Patterns
- ❌ Anti-pattern: Storing
DateTime directly in Firestore JSON models without @timestampConverter, resulting in ISO-8601 String storage instead of native Firestore Timestamps.
- ✔️ Correct: Use
@timestampConverter or UnionTimestamp so Firestore creates native indexable timestamps.
- ❌ Anti-pattern: Manually overriding
toJson() to inject FieldValue.serverTimestamp().
- ✔️ Correct: Use
@UnionTimestampConverter.alwaysServerTimestampConverter to declaratively emit server timestamps on write operations.