From 742b4aada8e69f6ad2054af7566de12a266c9ce8 Mon Sep 17 00:00:00 2001 From: Kosuke Saigusa Date: Mon, 5 Jun 2023 14:19:32 +0900 Subject: [PATCH 1/5] chore: remove unnecessary print from test --- test/flutterfire_json_converters_test.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/flutterfire_json_converters_test.dart b/test/flutterfire_json_converters_test.dart index ce361cc..1e6e5f9 100644 --- a/test/flutterfire_json_converters_test.dart +++ b/test/flutterfire_json_converters_test.dart @@ -22,8 +22,6 @@ void main() { final entity = Entity(name: 'foo', createdAt: ClientDateTime(epoch)); final json = entity.toJson(); - print(json['updatedAt']); - expect(json['name'], 'foo'); expect(json['createdAt'], Timestamp.fromDate(epoch)); expect(json['updatedAt'], isA()); From f38fd84f4e2c3ea0b03a1926094b3081ef7bd4da Mon Sep 17 00:00:00 2001 From: Kosuke Saigusa Date: Mon, 5 Jun 2023 14:20:09 +0900 Subject: [PATCH 2/5] chore: update comments in entity fields --- example/lib/main.dart | 7 +++---- example/lib/main.g.dart | 4 +++- test/helper/entity.dart | 7 +++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 27ab5fa..823a57b 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -11,20 +11,19 @@ class Entity { this.updatedAt = const ServerTimestamp(), }); - /// Connect the generated [_$EntityFromJson] function to the `fromJson` - /// factory. factory Entity.fromJson(Map json) => _$EntityFromJson(json); - /// The generated code assumes these values exist in JSON. final String name; + // Handle both Dart's `DateTime` and Cloud Firestore's `Timestamp` types. @sealedTimestampConverter final SealedTimestamp createdAt; + // Handle both Dart's `DateTime` and Cloud Firestore's `Timestamp` types, and + // always use `FieldValue.serverTimestamp()` when creating/updating a document. @alwaysUseServerTimestampSealedTimestampConverter final SealedTimestamp updatedAt; - /// Connect the generated [_$EntityToJson] function to the `toJson` method. Map toJson() => _$EntityToJson(this); } diff --git a/example/lib/main.g.dart b/example/lib/main.g.dart index 3754653..32b0961 100644 --- a/example/lib/main.g.dart +++ b/example/lib/main.g.dart @@ -1,12 +1,14 @@ // GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint, implicit_dynamic_parameter, implicit_dynamic_type, implicit_dynamic_method, strict_raw_type + part of 'main.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -Entity _$EntityFromJson(Map json) => Entity( +Entity _$EntityFromJson(Map json) => Entity( name: json['name'] as String, createdAt: json['createdAt'] == null ? const ServerTimestamp() diff --git a/test/helper/entity.dart b/test/helper/entity.dart index 726309a..68e594c 100644 --- a/test/helper/entity.dart +++ b/test/helper/entity.dart @@ -11,19 +11,18 @@ class Entity { this.updatedAt = const ServerTimestamp(), }); - /// Connect the generated [_$EntityFromJson] function to the `fromJson` - /// factory. factory Entity.fromJson(Map json) => _$EntityFromJson(json); - /// The generated code assumes these values exist in JSON. final String name; + // Handle both Dart's `DateTime` and Cloud Firestore's `Timestamp` types. @sealedTimestampConverter final SealedTimestamp createdAt; + // Handle both Dart's `DateTime` and Cloud Firestore's `Timestamp` types, and + // always use `FieldValue.serverTimestamp()` when creating/updating a document. @alwaysUseServerTimestampSealedTimestampConverter final SealedTimestamp updatedAt; - /// Connect the generated [_$EntityToJson] function to the `toJson` method. Map toJson() => _$EntityToJson(this); } From 51c6c5579daa7278609db346aa79471153b23826 Mon Sep 17 00:00:00 2001 From: Kosuke Saigusa Date: Mon, 5 Jun 2023 14:20:25 +0900 Subject: [PATCH 3/5] chore: add build.yaml alias to example project --- example/build.yaml | 1 + 1 file changed, 1 insertion(+) create mode 120000 example/build.yaml diff --git a/example/build.yaml b/example/build.yaml new file mode 120000 index 0000000..94aae85 --- /dev/null +++ b/example/build.yaml @@ -0,0 +1 @@ +../build.yaml \ No newline at end of file From 0661146156965d21625659001c4f5c475f9f0b74 Mon Sep 17 00:00:00 2001 From: Kosuke Saigusa Date: Mon, 5 Jun 2023 14:20:41 +0900 Subject: [PATCH 4/5] chore: fix pubspec.yaml homepage URL --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 417bde5..cc98d82 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: flutterfire_json_converters description: flutterfire_json_converters package supplies some useful json_converters for your FlutterFire apps. version: 0.0.1 -homepage: https://github.com/KosukeSaigusa/flutterfire_json_converters +homepage: https://github.com/KosukeSaigusa/flutterfire-json-converters environment: sdk: '>=3.0.0 <4.0.0' From 808050efdc7c6abdba69038a5d1c051ed5037092 Mon Sep 17 00:00:00 2001 From: Kosuke Saigusa Date: Mon, 5 Jun 2023 14:20:58 +0900 Subject: [PATCH 5/5] docs: update README.md --- README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9735852..f611bc5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ flutterfire_json_converters package supplies some useful json_converters when yo ### Requirements -This package uses Dart 3 features, so you need to use compatible Dart (Flutter SDK). +This package uses Dart 3 features, so you need to use compatible Dart (Flutter) SDK. ```yaml environment: @@ -40,6 +40,51 @@ When dealing with Cloud Firestore's `Timestamp` field, you may encounter the fol - During the creation or updating of Cloud Firestore documents, you may want to automatically set certain fields (e.g., `updatedAt`) to `FieldValue.serverTimestamp()`. - For other fields (e.g., `createdAt`), you might sometimes prefer to specify a client-side DateTime and save it to a Cloud Firestore document, while at other times you might want to automatically set it to `FieldValue.serverTimestamp()`. +For such scenarios, you can define `DateTime`/`Timestamp` fields as `SealedTimestamp` type with `@sealedTimestampConverter`/`@alwaysUseServerTimestampSealedTimestampConverter` json_converter annotations like below: + +```dart +@JsonSerializable() +class Entity { + Entity({ + required this.name, + this.createdAt = const ServerTimestamp(), + this.updatedAt = const ServerTimestamp(), + }); + + factory Entity.fromJson(Map json) => _$EntityFromJson(json); + + final String name; + + // Handle both Dart's `DateTime` and Cloud Firestore's `Timestamp` types. + @sealedTimestampConverter + final SealedTimestamp createdAt; + + // Handle both Dart's `DateTime` and Cloud Firestore's `Timestamp` types, and + // always use `FieldValue.serverTimestamp()` when creating/updating a document. + @alwaysUseServerTimestampSealedTimestampConverter + final SealedTimestamp updatedAt; + + Map toJson() => _$EntityToJson(this); +} +``` + +When you want to get `DateTime` value of their fields on Dart client-side, you can call `SealedTimestamp.dateTime`. + +```dart +final epoch = DateTime(1970); +final entity = Entity(name: 'foo', createdAt: ClientDateTime(epoch)); + +print(entity.name); // 'foo' +print(entity.createdAt.dateTime) // 1970-01-01 00:00:00.000 +print(entity.updatedAt.dateTime) // null + +final json = entity.toJson(); + +print(json['name']); // 'foo' +print(json['createdAt']); // Timestamp(seconds=0, nanoseconds=0) +print(json['updatedAt']); // FieldValue(Instance of 'MethodChannelFieldValue') +``` + ## Acknowledgements This package is developed with reference to: