diff --git a/fcm/lib/converter/fcm_token_nullable_converter.dart b/fcm/lib/converter/fcm_token_nullable_converter.dart new file mode 100644 index 000000000..7a9e017c8 --- /dev/null +++ b/fcm/lib/converter/fcm_token_nullable_converter.dart @@ -0,0 +1,12 @@ +import 'package:fcm/model/fcm_token.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class FcmTokenNullableConverter implements JsonConverter { + const FcmTokenNullableConverter(); + + @override + FcmToken? fromJson(String? json) => json != null ? FcmToken(json) : null; + + @override + String? toJson(FcmToken? object) => object?.value; +} diff --git a/fcm/lib/converter/firebase_expired_time_nullable_converter.dart b/fcm/lib/converter/firebase_expired_time_nullable_converter.dart deleted file mode 100644 index db1d076a0..000000000 --- a/fcm/lib/converter/firebase_expired_time_nullable_converter.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:fcm/model/firebase_expired_time.dart'; -import 'package:jmap_dart_client/http/converter/utc_date_converter.dart'; -import 'package:jmap_dart_client/http/converter/utc_date_nullable_converter.dart'; -import 'package:json_annotation/json_annotation.dart'; - -class FirebaseExpiredTimeNullableConverter implements JsonConverter { - const FirebaseExpiredTimeNullableConverter(); - - @override - FirebaseExpiredTime? fromJson(String? json) { - if (json != null) { - return FirebaseExpiredTime(const UTCDateConverter().fromJson(json)); - } else { - return null; - } - } - - @override - String? toJson(FirebaseExpiredTime? object) => const UTCDateNullableConverter().toJson(object?.value); -} \ No newline at end of file diff --git a/fcm/lib/converter/firebase_registration_expired_time_nullable_converter.dart b/fcm/lib/converter/firebase_registration_expired_time_nullable_converter.dart new file mode 100644 index 000000000..34b8e2d5c --- /dev/null +++ b/fcm/lib/converter/firebase_registration_expired_time_nullable_converter.dart @@ -0,0 +1,20 @@ +import 'package:fcm/model/firebase_registration_expired_time.dart'; +import 'package:jmap_dart_client/http/converter/utc_date_converter.dart'; +import 'package:jmap_dart_client/http/converter/utc_date_nullable_converter.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class FirebaseRegistrationExpiredTimeNullableConverter implements JsonConverter { + const FirebaseRegistrationExpiredTimeNullableConverter(); + + @override + FirebaseRegistrationExpiredTime? fromJson(String? json) { + if (json != null) { + return FirebaseRegistrationExpiredTime(const UTCDateConverter().fromJson(json)); + } else { + return null; + } + } + + @override + String? toJson(FirebaseRegistrationExpiredTime? object) => const UTCDateNullableConverter().toJson(object?.value); +} \ No newline at end of file diff --git a/fcm/lib/converter/firebase_registration_id_nullable_converter.dart b/fcm/lib/converter/firebase_registration_id_nullable_converter.dart new file mode 100644 index 000000000..07b5b3ffc --- /dev/null +++ b/fcm/lib/converter/firebase_registration_id_nullable_converter.dart @@ -0,0 +1,13 @@ +import 'package:fcm/model/firebase_registration_id.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class FirebaseRegistrationIdNullableConverter implements JsonConverter { + const FirebaseRegistrationIdNullableConverter(); + + @override + FirebaseRegistrationId? fromJson(String? json) => json != null ? FirebaseRegistrationId(Id(json)) : null; + + @override + String? toJson(FirebaseRegistrationId? object) => object?.id.value; +} diff --git a/fcm/lib/converter/firebase_subscription_id_nullable_converter.dart b/fcm/lib/converter/firebase_subscription_id_nullable_converter.dart deleted file mode 100644 index 816e71763..000000000 --- a/fcm/lib/converter/firebase_subscription_id_nullable_converter.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:fcm/model/firebase_subscription_id.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; -import 'package:json_annotation/json_annotation.dart'; - -class FirebaseSubscriptionIdNullableConverter implements JsonConverter { - const FirebaseSubscriptionIdNullableConverter(); - - @override - FirebaseSubscriptionId? fromJson(String? json) => json != null ? FirebaseSubscriptionId(Id(json)) : null; - - @override - String? toJson(FirebaseSubscriptionId? object) => object?.id.value; -} diff --git a/fcm/lib/converter/firebase_token_nullable_converter.dart b/fcm/lib/converter/firebase_token_nullable_converter.dart deleted file mode 100644 index 62b66aac0..000000000 --- a/fcm/lib/converter/firebase_token_nullable_converter.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:fcm/model/firebase_token.dart'; -import 'package:json_annotation/json_annotation.dart'; - -class FirebaseTokenNullableConverter implements JsonConverter { - const FirebaseTokenNullableConverter(); - - @override - FirebaseToken? fromJson(String? json) => json != null ? FirebaseToken(json) : null; - - @override - String? toJson(FirebaseToken? object) => object?.value; -} diff --git a/fcm/lib/method/get/firebase_subscription_get_method.dart b/fcm/lib/method/get/firebase_registration_get_method.dart similarity index 74% rename from fcm/lib/method/get/firebase_subscription_get_method.dart rename to fcm/lib/method/get/firebase_registration_get_method.dart index e236370cc..5369f7490 100644 --- a/fcm/lib/method/get/firebase_subscription_get_method.dart +++ b/fcm/lib/method/get/firebase_registration_get_method.dart @@ -7,14 +7,14 @@ import 'package:jmap_dart_client/jmap/core/request/request_invocation.dart'; import 'package:jmap_dart_client/jmap/core/request/result_reference.dart'; import 'package:json_annotation/json_annotation.dart'; -part 'firebase_subscription_get_method.g.dart'; +part 'firebase_registration_get_method.g.dart'; @IdConverter() @PropertiesConverter() @JsonSerializable(explicitToJson: true) -class FirebaseSubscriptionGetMethod extends GetMethodNoNeedAccountId { +class FirebaseRegistrationGetMethod extends GetMethodNoNeedAccountId { - FirebaseSubscriptionGetMethod() : super(); + FirebaseRegistrationGetMethod() : super(); @override MethodName get methodName => MethodName('FirebaseRegistration/get'); @@ -28,8 +28,8 @@ class FirebaseSubscriptionGetMethod extends GetMethodNoNeedAccountId { @override List get props => [methodName, ids, requiredCapabilities]; - factory FirebaseSubscriptionGetMethod.fromJson(Map json) => _$FirebaseSubscriptionGetMethodFromJson(json); + factory FirebaseRegistrationGetMethod.fromJson(Map json) => _$FirebaseRegistrationGetMethodFromJson(json); @override - Map toJson() => _$FirebaseSubscriptionGetMethodToJson(this); + Map toJson() => _$FirebaseRegistrationGetMethodToJson(this); } \ No newline at end of file diff --git a/fcm/lib/method/get/firebase_registration_get_response.dart b/fcm/lib/method/get/firebase_registration_get_response.dart new file mode 100644 index 000000000..a8a418fb7 --- /dev/null +++ b/fcm/lib/method/get/firebase_registration_get_response.dart @@ -0,0 +1,29 @@ +import 'package:fcm/model/firebase_registration.dart'; +import 'package:jmap_dart_client/http/converter/id_converter.dart'; +import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:jmap_dart_client/jmap/core/method/response/get_response.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'firebase_registration_get_response.g.dart'; + +@IdConverter() +@JsonSerializable(explicitToJson: true) +class FirebaseRegistrationGetResponse extends GetResponseNoAccountId { + + FirebaseRegistrationGetResponse( + List list, + List? notFound + ) : super(list, notFound); + + factory FirebaseRegistrationGetResponse.fromJson(Map json) => + _$FirebaseRegistrationGetResponseFromJson(json); + + static FirebaseRegistrationGetResponse deserialize(Map json) { + return FirebaseRegistrationGetResponse.fromJson(json); + } + + Map toJson() => _$FirebaseRegistrationGetResponseToJson(this); + + @override + List get props => [list, notFound]; +} \ No newline at end of file diff --git a/fcm/lib/method/get/firebase_subscription_get_response.dart b/fcm/lib/method/get/firebase_subscription_get_response.dart deleted file mode 100644 index 6704d65a5..000000000 --- a/fcm/lib/method/get/firebase_subscription_get_response.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:fcm/model/firebase_subscription.dart'; -import 'package:jmap_dart_client/http/converter/id_converter.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; -import 'package:jmap_dart_client/jmap/core/method/response/get_response.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'firebase_subscription_get_response.g.dart'; - -@IdConverter() -@JsonSerializable(explicitToJson: true) -class FirebaseSubscriptionGetResponse extends GetResponseNoAccountId { - - FirebaseSubscriptionGetResponse( - List list, - List? notFound - ) : super(list, notFound); - - factory FirebaseSubscriptionGetResponse.fromJson(Map json) => - _$FirebaseSubscriptionGetResponseFromJson(json); - - static FirebaseSubscriptionGetResponse deserialize(Map json) { - return FirebaseSubscriptionGetResponse.fromJson(json); - } - - Map toJson() => _$FirebaseSubscriptionGetResponseToJson(this); - - @override - List get props => [list, notFound]; -} \ No newline at end of file diff --git a/fcm/lib/method/set/firebase_subscription_set_method.dart b/fcm/lib/method/set/firebase_registration_set_method.dart similarity index 87% rename from fcm/lib/method/set/firebase_subscription_set_method.dart rename to fcm/lib/method/set/firebase_registration_set_method.dart index 4ac4a687a..6c1908abb 100644 --- a/fcm/lib/method/set/firebase_subscription_set_method.dart +++ b/fcm/lib/method/set/firebase_registration_set_method.dart @@ -1,4 +1,4 @@ -import 'package:fcm/model/firebase_subscription.dart'; +import 'package:fcm/model/firebase_registration.dart'; import 'package:fcm/model/firebase_capability.dart'; import 'package:jmap_dart_client/http/converter/id_converter.dart'; import 'package:jmap_dart_client/http/converter/set/set_method_properties_converter.dart'; @@ -6,9 +6,9 @@ import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart import 'package:jmap_dart_client/jmap/core/method/request/set_method.dart'; import 'package:jmap_dart_client/jmap/core/request/request_invocation.dart'; -class FirebaseSubscriptionSetMethod extends SetMethodNoNeedAccountId { +class FirebaseRegistrationSetMethod extends SetMethodNoNeedAccountId { - FirebaseSubscriptionSetMethod() : super(); + FirebaseRegistrationSetMethod() : super(); @override MethodName get methodName => MethodName('FirebaseRegistration/set'); diff --git a/fcm/lib/method/set/firebase_subscription_set_response.dart b/fcm/lib/method/set/firebase_registration_set_response.dart similarity index 77% rename from fcm/lib/method/set/firebase_subscription_set_response.dart rename to fcm/lib/method/set/firebase_registration_set_response.dart index 8d093b4be..b9dd2813f 100644 --- a/fcm/lib/method/set/firebase_subscription_set_response.dart +++ b/fcm/lib/method/set/firebase_registration_set_response.dart @@ -1,13 +1,13 @@ -import 'package:fcm/model/firebase_subscription.dart'; +import 'package:fcm/model/firebase_registration.dart'; import 'package:jmap_dart_client/http/converter/id_converter.dart'; import 'package:jmap_dart_client/jmap/core/error/set_error.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/method/response/set_response.dart'; -class FirebaseSubscriptionSetResponse extends SetResponseNoAccount { - FirebaseSubscriptionSetResponse({ - Map? created, - Map? updated, +class FirebaseRegistrationSetResponse extends SetResponseNoAccount { + FirebaseRegistrationSetResponse({ + Map? created, + Map? updated, Set? destroyed, Map? notCreated, Map? notUpdated, @@ -21,15 +21,15 @@ class FirebaseSubscriptionSetResponse extends SetResponseNoAccount json) { - return FirebaseSubscriptionSetResponse( + static FirebaseRegistrationSetResponse deserialize(Map json) { + return FirebaseRegistrationSetResponse( created: (json['created'] as Map?)?.map((key, value) => MapEntry( const IdConverter().fromJson(key), - FirebaseSubscription.fromJson(value as Map) + FirebaseRegistration.fromJson(value as Map) )), updated: (json['updated'] as Map?)?.map((key, value) => MapEntry( const IdConverter().fromJson(key), - value != null ? FirebaseSubscription.fromJson(value as Map) : null + value != null ? FirebaseRegistration.fromJson(value as Map) : null )), destroyed: (json['destroyed'] as List?)?.map((id) => const IdConverter().fromJson(id)).toSet(), notCreated: (json['notCreated'] as Map?)?.map((key, value) => MapEntry( diff --git a/fcm/lib/model/firebase_token.dart b/fcm/lib/model/fcm_token.dart similarity index 63% rename from fcm/lib/model/firebase_token.dart rename to fcm/lib/model/fcm_token.dart index c6e82567b..b7e1897c7 100644 --- a/fcm/lib/model/firebase_token.dart +++ b/fcm/lib/model/fcm_token.dart @@ -1,11 +1,11 @@ import 'package:equatable/equatable.dart'; -class FirebaseToken with EquatableMixin { +class FcmToken with EquatableMixin { final String value; - FirebaseToken(this.value); + FcmToken(this.value); @override List get props => [value]; diff --git a/fcm/lib/model/firebase_registration.dart b/fcm/lib/model/firebase_registration.dart new file mode 100644 index 000000000..bdc73ed5e --- /dev/null +++ b/fcm/lib/model/firebase_registration.dart @@ -0,0 +1,45 @@ + +import 'package:equatable/equatable.dart'; +import 'package:fcm/converter/device_client_id_nullable_converter.dart'; +import 'package:fcm/converter/firebase_registration_expired_time_nullable_converter.dart'; +import 'package:fcm/converter/firebase_registration_id_nullable_converter.dart'; +import 'package:fcm/converter/fcm_token_nullable_converter.dart'; +import 'package:fcm/converter/type_name_converter.dart'; +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/firebase_registration_expired_time.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; +import 'package:fcm/model/fcm_token.dart'; +import 'package:fcm/model/type_name.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'firebase_registration.g.dart'; + +@DeviceClientIdNullableConverter() +@FirebaseRegistrationIdNullableConverter() +@FcmTokenNullableConverter() +@FirebaseRegistrationExpiredTimeNullableConverter() +@TypeNameConverter() +@JsonSerializable(explicitToJson: true, includeIfNull: false) +class FirebaseRegistration with EquatableMixin { + + final FirebaseRegistrationId? id; + final FcmToken? token; + final DeviceClientId? deviceClientId; + final FirebaseRegistrationExpiredTime? expires; + final List? types; + + FirebaseRegistration({ + this.id, + this.token, + this.deviceClientId, + this.expires, + this.types + }); + + factory FirebaseRegistration.fromJson(Map json) => _$FirebaseRegistrationFromJson(json); + + Map toJson() => _$FirebaseRegistrationToJson(this); + + @override + List get props => [id, token, deviceClientId, expires, types]; +} \ No newline at end of file diff --git a/fcm/lib/model/firebase_expired_time.dart b/fcm/lib/model/firebase_registration_expired_time.dart similarity index 62% rename from fcm/lib/model/firebase_expired_time.dart rename to fcm/lib/model/firebase_registration_expired_time.dart index c0cc619dc..e8e169bd8 100644 --- a/fcm/lib/model/firebase_expired_time.dart +++ b/fcm/lib/model/firebase_registration_expired_time.dart @@ -2,11 +2,11 @@ import 'package:equatable/equatable.dart'; import 'package:jmap_dart_client/jmap/core/utc_date.dart'; -class FirebaseExpiredTime with EquatableMixin { +class FirebaseRegistrationExpiredTime with EquatableMixin { final UTCDate value; - FirebaseExpiredTime(this.value); + FirebaseRegistrationExpiredTime(this.value); @override List get props => [value]; diff --git a/fcm/lib/model/firebase_subscription_id.dart b/fcm/lib/model/firebase_registration_id.dart similarity index 65% rename from fcm/lib/model/firebase_subscription_id.dart rename to fcm/lib/model/firebase_registration_id.dart index 267952546..2f06b6784 100644 --- a/fcm/lib/model/firebase_subscription_id.dart +++ b/fcm/lib/model/firebase_registration_id.dart @@ -2,11 +2,11 @@ import 'package:equatable/equatable.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; -class FirebaseSubscriptionId with EquatableMixin { +class FirebaseRegistrationId with EquatableMixin { final Id id; - FirebaseSubscriptionId(this.id); + FirebaseRegistrationId(this.id); @override List get props => [id]; diff --git a/fcm/lib/model/firebase_subscription.dart b/fcm/lib/model/firebase_subscription.dart deleted file mode 100644 index 054601746..000000000 --- a/fcm/lib/model/firebase_subscription.dart +++ /dev/null @@ -1,45 +0,0 @@ - -import 'package:equatable/equatable.dart'; -import 'package:fcm/converter/device_client_id_nullable_converter.dart'; -import 'package:fcm/converter/firebase_expired_time_nullable_converter.dart'; -import 'package:fcm/converter/firebase_subscription_id_nullable_converter.dart'; -import 'package:fcm/converter/firebase_token_nullable_converter.dart'; -import 'package:fcm/converter/type_name_converter.dart'; -import 'package:fcm/model/device_client_id.dart'; -import 'package:fcm/model/firebase_expired_time.dart'; -import 'package:fcm/model/firebase_subscription_id.dart'; -import 'package:fcm/model/firebase_token.dart'; -import 'package:fcm/model/type_name.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'firebase_subscription.g.dart'; - -@DeviceClientIdNullableConverter() -@FirebaseSubscriptionIdNullableConverter() -@FirebaseTokenNullableConverter() -@FirebaseExpiredTimeNullableConverter() -@TypeNameConverter() -@JsonSerializable(explicitToJson: true, includeIfNull: false) -class FirebaseSubscription with EquatableMixin { - - final FirebaseSubscriptionId? id; - final FirebaseToken? token; - final DeviceClientId? deviceClientId; - final FirebaseExpiredTime? expires; - final List? types; - - FirebaseSubscription({ - this.id, - this.token, - this.deviceClientId, - this.expires, - this.types - }); - - factory FirebaseSubscription.fromJson(Map json) => _$FirebaseSubscriptionFromJson(json); - - Map toJson() => _$FirebaseSubscriptionToJson(this); - - @override - List get props => [id, token, deviceClientId, expires, types]; -} \ No newline at end of file diff --git a/fcm/test/method/firebase_subscription_get_method_test.dart b/fcm/test/method/firebase_registration_get_method_test.dart similarity index 65% rename from fcm/test/method/firebase_subscription_get_method_test.dart rename to fcm/test/method/firebase_registration_get_method_test.dart index c91da43b7..923c58e2f 100644 --- a/fcm/test/method/firebase_subscription_get_method_test.dart +++ b/fcm/test/method/firebase_registration_get_method_test.dart @@ -1,10 +1,10 @@ import 'package:dio/dio.dart'; -import 'package:fcm/method/get/firebase_subscription_get_method.dart'; -import 'package:fcm/method/get/firebase_subscription_get_response.dart'; +import 'package:fcm/method/get/firebase_registration_get_method.dart'; +import 'package:fcm/method/get/firebase_registration_get_response.dart'; import 'package:fcm/model/device_client_id.dart'; -import 'package:fcm/model/firebase_expired_time.dart'; -import 'package:fcm/model/firebase_subscription.dart'; -import 'package:fcm/model/firebase_subscription_id.dart'; +import 'package:fcm/model/firebase_registration_expired_time.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; import 'package:fcm/model/type_name.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:http_mock_adapter/http_mock_adapter.dart'; @@ -14,22 +14,22 @@ import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:jmap_dart_client/jmap/jmap_request.dart'; void main() { - group('test to json firebase subscription get method', () { - final expectFirebaseSubscription1 = FirebaseSubscription( - id: FirebaseSubscriptionId(Id('e50b2c1d-9553-41a3-b0a7-a7d26b599ee1')), + group('test to json firebase registration get method', () { + final expectFirebaseRegistration1 = FirebaseRegistration( + id: FirebaseRegistrationId(Id('e50b2c1d-9553-41a3-b0a7-a7d26b599ee1')), deviceClientId: DeviceClientId('b37ff8001ca0'), - expires: FirebaseExpiredTime(UTCDate(DateTime.parse('2018-07-31T00:13:21Z'))), + expires: FirebaseRegistrationExpiredTime(UTCDate(DateTime.parse('2018-07-31T00:13:21Z'))), types: [TypeName.mailboxType], ); - final expectFirebaseSubscription2 = FirebaseSubscription( - id: FirebaseSubscriptionId(Id('f2d0aab5-e976-4e8b-ad4b-b380a5b987e4')), + final expectFirebaseRegistration2 = FirebaseRegistration( + id: FirebaseRegistrationId(Id('f2d0aab5-e976-4e8b-ad4b-b380a5b987e4')), deviceClientId: DeviceClientId('X8980fc'), - expires: FirebaseExpiredTime(UTCDate(DateTime.parse('2018-07-12T05:55:00Z'))), + expires: FirebaseRegistrationExpiredTime(UTCDate(DateTime.parse('2018-07-12T05:55:00Z'))), types: [TypeName.mailboxType, TypeName.emailType, TypeName.emailDelivery], ); - test('firebase subscription get method and response parsing', () async { + test('firebase registration get method and response parsing', () async { final baseOption = BaseOptions(method: 'POST'); final dio = Dio(baseOption)..options.baseUrl = 'http://domain.com/jmap'; final dioAdapter = DioAdapter(dio: dio); @@ -84,20 +84,20 @@ void main() { final processingInvocation = ProcessingInvocation(); final requestBuilder = JmapRequestBuilder(httpClient, processingInvocation); - final firebaseSubscriptionGetMethod = FirebaseSubscriptionGetMethod(); - final firebaseSubscriptionGetInvocation = requestBuilder.invocation(firebaseSubscriptionGetMethod); + final firebaseRegistrationGetMethod = FirebaseRegistrationGetMethod(); + final firebaseRegistrationGetInvocation = requestBuilder.invocation(firebaseRegistrationGetMethod); final response = await (requestBuilder - ..usings(firebaseSubscriptionGetMethod.requiredCapabilities)) + ..usings(firebaseRegistrationGetMethod.requiredCapabilities)) .build() .execute(); - final resultList = response.parse( - firebaseSubscriptionGetInvocation.methodCallId, - FirebaseSubscriptionGetResponse.deserialize + final resultList = response.parse( + firebaseRegistrationGetInvocation.methodCallId, + FirebaseRegistrationGetResponse.deserialize ); expect(resultList?.list.length, equals(2)); - expect(resultList?.list, containsAll([expectFirebaseSubscription1, expectFirebaseSubscription2])); + expect(resultList?.list, containsAll([expectFirebaseRegistration1, expectFirebaseRegistration2])); }); }); } \ No newline at end of file diff --git a/fcm/test/method/firebase_subscription_set_method_test.dart b/fcm/test/method/firebase_registration_set_method_test.dart similarity index 65% rename from fcm/test/method/firebase_subscription_set_method_test.dart rename to fcm/test/method/firebase_registration_set_method_test.dart index 86379c17f..fee8cf0d4 100644 --- a/fcm/test/method/firebase_subscription_set_method_test.dart +++ b/fcm/test/method/firebase_registration_set_method_test.dart @@ -1,11 +1,11 @@ import 'package:dio/dio.dart'; -import 'package:fcm/method/set/firebase_subscription_set_method.dart'; -import 'package:fcm/method/set/firebase_subscription_set_response.dart'; +import 'package:fcm/method/set/firebase_registration_set_method.dart'; +import 'package:fcm/method/set/firebase_registration_set_response.dart'; import 'package:fcm/model/device_client_id.dart'; -import 'package:fcm/model/firebase_expired_time.dart'; -import 'package:fcm/model/firebase_subscription.dart'; -import 'package:fcm/model/firebase_subscription_id.dart'; -import 'package:fcm/model/firebase_token.dart'; +import 'package:fcm/model/firebase_registration_expired_time.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; +import 'package:fcm/model/fcm_token.dart'; import 'package:fcm/model/type_name.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:http_mock_adapter/http_mock_adapter.dart'; @@ -15,13 +15,13 @@ import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:jmap_dart_client/jmap/jmap_request.dart'; void main() { - group('test to json firebase subscription set method', () { - final expectedFirebaseSubscriptionCreated = FirebaseSubscription( - id: FirebaseSubscriptionId(Id('175dbd70-93d1-11ec-984e-e3f8b83572b4')), - expires: FirebaseExpiredTime(UTCDate(DateTime.parse('2022-03-31T02:14:29Z'))), + group('test to json firebase registration set method', () { + final expectedFirebaseRegistrationCreated = FirebaseRegistration( + id: FirebaseRegistrationId(Id('175dbd70-93d1-11ec-984e-e3f8b83572b4')), + expires: FirebaseRegistrationExpiredTime(UTCDate(DateTime.parse('2022-03-31T02:14:29Z'))), ); - test('firebase subscription set method and response parsing', () async { + test('firebase registration set method and response parsing', () async { final baseOption = BaseOptions(method: 'POST'); final dio = Dio(baseOption) ..options.baseUrl = 'http://domain.com/jmap'; @@ -75,31 +75,31 @@ void main() { final createRequestId = Id('dab246'); - final firebaseSubscriptionSetMethod = FirebaseSubscriptionSetMethod() + final firebaseRegistrationSetMethod = FirebaseRegistrationSetMethod() ..addCreate( createRequestId, - FirebaseSubscription( + FirebaseRegistration( deviceClientId: DeviceClientId('a123-b123-c123'), - token: FirebaseToken('token1'), + token: FcmToken('token1'), types: [TypeName.mailboxType] ) ); final httpClient = HttpClient(dio); final requestBuilder = JmapRequestBuilder(httpClient, ProcessingInvocation()); - final firebaseSubscriptionSetInvocation = requestBuilder.invocation(firebaseSubscriptionSetMethod); + final firebaseRegistrationSetInvocation = requestBuilder.invocation(firebaseRegistrationSetMethod); final response = await (requestBuilder - ..usings(firebaseSubscriptionSetMethod.requiredCapabilities)) + ..usings(firebaseRegistrationSetMethod.requiredCapabilities)) .build() .execute(); - final firebaseSubscriptionSetResponse = response.parse( - firebaseSubscriptionSetInvocation.methodCallId, - FirebaseSubscriptionSetResponse.deserialize); + final firebaseRegistrationSetResponse = response.parse( + firebaseRegistrationSetInvocation.methodCallId, + FirebaseRegistrationSetResponse.deserialize); expect( - firebaseSubscriptionSetResponse!.created![createRequestId]!.id, - equals(expectedFirebaseSubscriptionCreated.id) + firebaseRegistrationSetResponse!.created![createRequestId]!.id, + equals(expectedFirebaseRegistrationCreated.id) ); }); }); diff --git a/lib/features/base/base_controller.dart b/lib/features/base/base_controller.dart index 99baa3415..24bbc9f8a 100644 --- a/lib/features/base/base_controller.dart +++ b/lib/features/base/base_controller.dart @@ -12,6 +12,7 @@ import 'package:core/utils/fps_manager.dart'; import 'package:core/utils/platform_info.dart'; import 'package:dartz/dartz.dart'; import 'package:fcm/model/firebase_capability.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:forward/forward/capability_forward.dart'; @@ -38,10 +39,10 @@ import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oi import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/bindings/email_rules_interactor_bindings.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/forward/bindings/forwarding_interactors_bindings.dart'; import 'package:tmail_ui_user/features/push_notification/domain/exceptions/fcm_exception.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/destroy_subscription_state.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/get_fcm_subscription_local.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/destroy_subscription_interactor.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_fcm_subscription_local_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/destroy_firebase_registration_state.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/get_stored_firebase_registration_state.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/destroy_firebase_registration_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_stored_firebase_registration_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/config/fcm_configuration.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/controller/fcm_message_controller.dart'; @@ -76,8 +77,8 @@ abstract class BaseController extends GetxController final _fcmReceiver = FcmReceiver.instance; bool _isFcmEnabled = false; - GetFCMSubscriptionLocalInteractor? _getSubscriptionLocalInteractor; - DestroySubscriptionInteractor? _destroySubscriptionInteractor; + GetStoredFirebaseRegistrationInteractor? _getStoredFirebaseRegistrationInteractor; + DestroyFirebaseRegistrationInteractor? _destroyFirebaseRegistrationInteractor; final viewState = Rx>(Right(UIState.idle)); FpsCallback? fpsCallback; @@ -180,12 +181,12 @@ abstract class BaseController extends GetxController logError('BaseController::handleFailureViewState(): ${failure.runtimeType}'); if (failure is LogoutOidcFailure) { if (_isFcmEnabled) { - _getSubscriptionLocalAction(); + _getStoredFirebaseRegistrationFromCache(); } else { await clearDataAndGoToLoginPage(); } - } else if (failure is GetFCMSubscriptionLocalFailure || - failure is DestroySubscriptionFailure) { + } else if (failure is GetStoredFirebaseRegistrationFailure || + failure is DestroyFirebaseRegistrationFailure) { await clearDataAndGoToLoginPage(); } } @@ -194,13 +195,13 @@ abstract class BaseController extends GetxController log('BaseController::handleSuccessViewState(): ${success.runtimeType}'); if (success is LogoutOidcSuccess) { if (_isFcmEnabled) { - _getSubscriptionLocalAction(); + _getStoredFirebaseRegistrationFromCache(); } else { await clearDataAndGoToLoginPage(); } - } else if (success is GetFCMSubscriptionLocalSuccess) { - _destroySubscriptionAction(success.fcmSubscription.subscriptionId); - } else if (success is DestroySubscriptionSuccess) { + } else if (success is GetStoredFirebaseRegistrationSuccess) { + _destroyFirebaseRegistration(success.firebaseRegistration.id!); + } else if (success is DestroyFirebaseRegistrationSuccess) { await clearDataAndGoToLoginPage(); } } @@ -265,7 +266,7 @@ abstract class BaseController extends GetxController if (AppConfig.fcmAvailable) { final mapEnvData = Map.from(dotenv.env); await AppUtils.loadFcmConfigFileToEnv(currentMapEnvData: mapEnvData); - FcmConfiguration.initialize(); + await FcmConfiguration.initialize(); FcmInteractorBindings().dependencies(); FcmMessageController.instance.initializeFromAccountId(accountId, session); } else { @@ -299,26 +300,26 @@ abstract class BaseController extends GetxController consumeState(logoutOidcInteractor.execute()); } else { if (_isFcmEnabled) { - _getSubscriptionLocalAction(); + _getStoredFirebaseRegistrationFromCache(); } else { await clearDataAndGoToLoginPage(); } } } - void _destroySubscriptionAction(String subscriptionId) async { - _destroySubscriptionInteractor = getBinding(); - if (_destroySubscriptionInteractor != null) { - consumeState(_destroySubscriptionInteractor!.execute(subscriptionId)); + void _destroyFirebaseRegistration(FirebaseRegistrationId firebaseRegistrationId) async { + _destroyFirebaseRegistrationInteractor = getBinding(); + if (_destroyFirebaseRegistrationInteractor != null) { + consumeState(_destroyFirebaseRegistrationInteractor!.execute(firebaseRegistrationId)); } else { await clearDataAndGoToLoginPage(); } } - void _getSubscriptionLocalAction() async { - _getSubscriptionLocalInteractor = getBinding(); - if (_getSubscriptionLocalInteractor != null) { - consumeState(_getSubscriptionLocalInteractor!.execute()); + void _getStoredFirebaseRegistrationFromCache() async { + _getStoredFirebaseRegistrationInteractor = getBinding(); + if (_getStoredFirebaseRegistrationInteractor != null) { + consumeState(_getStoredFirebaseRegistrationInteractor!.execute()); } else { await clearDataAndGoToLoginPage(); } diff --git a/lib/features/caching/caching_manager.dart b/lib/features/caching/caching_manager.dart index bfc4447c1..eff5072e0 100644 --- a/lib/features/caching/caching_manager.dart +++ b/lib/features/caching/caching_manager.dart @@ -14,7 +14,7 @@ import 'package:tmail_ui_user/features/caching/clients/hive_cache_version_client import 'package:tmail_ui_user/features/caching/clients/mailbox_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/recent_search_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/state_cache_client.dart'; -import 'package:tmail_ui_user/features/caching/clients/subscription_cache_client.dart'; +import 'package:tmail_ui_user/features/caching/clients/firebase_registration_cache_client.dart'; import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart'; import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_spam_report_manager.dart'; @@ -28,7 +28,7 @@ class CachingManager { final RecentSearchCacheClient _recentSearchCacheClient; final AccountCacheClient _accountCacheClient; final FcmCacheClient _fcmCacheClient; - final FCMSubscriptionCacheClient _fcmSubscriptionCacheClient; + final FirebaseRegistrationCacheClient _firebaseRegistrationCacheClient; final HiveCacheVersionClient _hiveCacheVersionClient; final NewEmailHiveCacheClient _newEmailHiveCacheClient; final OpenedEmailHiveCacheClient _openedEmailHiveCacheClient; @@ -44,7 +44,7 @@ class CachingManager { this._recentSearchCacheClient, this._accountCacheClient, this._fcmCacheClient, - this._fcmSubscriptionCacheClient, + this._firebaseRegistrationCacheClient, this._hiveCacheVersionClient, this._newEmailHiveCacheClient, this._openedEmailHiveCacheClient, @@ -60,7 +60,7 @@ class CachingManager { _mailboxCacheClient.clearAllData(), _emailCacheClient.clearAllData(), _fcmCacheClient.clearAllData(), - _fcmSubscriptionCacheClient.clearAllData(), + _firebaseRegistrationCacheClient.clearAllData(), _recentSearchCacheClient.clearAllData(), _accountCacheClient.clearAllData(), _localSpamReportManager.clear(), @@ -80,7 +80,7 @@ class CachingManager { _mailboxCacheClient.clearAllData(), _emailCacheClient.clearAllData(), _fcmCacheClient.clearAllData(), - _fcmSubscriptionCacheClient.clearAllData(), + _firebaseRegistrationCacheClient.clearAllData(), _recentSearchCacheClient.clearAllData(), _localSpamReportManager.clear(), if (PlatformInfo.isMobile) diff --git a/lib/features/caching/clients/firebase_registration_cache_client.dart b/lib/features/caching/clients/firebase_registration_cache_client.dart new file mode 100644 index 000000000..d74d5c6fe --- /dev/null +++ b/lib/features/caching/clients/firebase_registration_cache_client.dart @@ -0,0 +1,10 @@ + +import 'package:tmail_ui_user/features/caching/config/hive_cache_client.dart'; +import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart'; +import 'package:tmail_ui_user/features/push_notification/data/model/firebase_registration_cache.dart'; + +class FirebaseRegistrationCacheClient extends HiveCacheClient { + + @override + String get tableName => CachingConstants.firebaseRegistrationCacheBoxName; +} \ No newline at end of file diff --git a/lib/features/caching/clients/subscription_cache_client.dart b/lib/features/caching/clients/subscription_cache_client.dart deleted file mode 100644 index 62b76ae3a..000000000 --- a/lib/features/caching/clients/subscription_cache_client.dart +++ /dev/null @@ -1,9 +0,0 @@ - -import 'package:tmail_ui_user/features/caching/config/hive_cache_client.dart'; -import 'package:tmail_ui_user/features/push_notification/data/model/fcm_subscription.dart'; - -class FCMSubscriptionCacheClient extends HiveCacheClient { - - @override - String get tableName => 'FCMSubscriptionCache'; -} \ No newline at end of file diff --git a/lib/features/caching/config/hive_cache_config.dart b/lib/features/caching/config/hive_cache_config.dart index 5b0cec2bd..0162c67d7 100644 --- a/lib/features/caching/config/hive_cache_config.dart +++ b/lib/features/caching/config/hive_cache_config.dart @@ -26,7 +26,7 @@ import 'package:tmail_ui_user/features/offline_mode/model/attachment_hive_cache. import 'package:tmail_ui_user/features/offline_mode/model/detailed_email_hive_cache.dart'; import 'package:tmail_ui_user/features/offline_mode/model/email_header_hive_cache.dart'; import 'package:tmail_ui_user/features/offline_mode/model/sending_email_hive_cache.dart'; -import 'package:tmail_ui_user/features/push_notification/data/model/fcm_subscription.dart'; +import 'package:tmail_ui_user/features/push_notification/data/model/firebase_registration_cache.dart'; import 'package:tmail_ui_user/features/thread/data/model/email_address_hive_cache.dart'; import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart'; import 'package:tmail_ui_user/main/bindings/network/binding_tag.dart'; @@ -145,9 +145,9 @@ class HiveCacheConfig { RecentLoginUsernameCacheAdapter(), CachingConstants.RECENT_LOGIN_USERNAME_HIVE_CACHE_IDENTITY ); - registerCacheAdapter( - FCMSubscriptionCacheAdapter(), - CachingConstants.FCM_SUBSCRIPTION_HIVE_CACHE_IDENTITY + registerCacheAdapter( + FirebaseRegistrationCacheAdapter(), + CachingConstants.FIREBASE_REGISTRATION_HIVE_CACHE_IDENTITY ); registerCacheAdapter( AttachmentHiveCacheAdapter(), diff --git a/lib/features/caching/utils/caching_constants.dart b/lib/features/caching/utils/caching_constants.dart index d73009966..4e1260cc8 100644 --- a/lib/features/caching/utils/caching_constants.dart +++ b/lib/features/caching/utils/caching_constants.dart @@ -13,7 +13,7 @@ class CachingConstants { static const int AUTHENTICATION_INFO_HIVE_CACHE_IDENTIFY = 11; static const int RECENT_LOGIN_URL_HIVE_CACHE_IDENTITY = 12; static const int RECENT_LOGIN_USERNAME_HIVE_CACHE_IDENTITY = 13; - static const int FCM_SUBSCRIPTION_HIVE_CACHE_IDENTITY = 14; + static const int FIREBASE_REGISTRATION_HIVE_CACHE_IDENTITY = 14; static const int ATTACHMENT_HIVE_CACHE_ID = 15; static const int EMAIL_HEADER_HIVE_CACHE_ID = 16; static const int DETAILED_EMAIL_HIVE_CACHE_ID = 17; @@ -25,6 +25,7 @@ class CachingConstants { static const String openedEmailCacheBoxName = 'opened_email_cache_box'; static const String sendingEmailCacheBoxName = 'sending_email_cache_box'; static const String sessionCacheBoxName = 'session_cache_box'; + static const String firebaseRegistrationCacheBoxName = 'firebase_registration_cache_box'; static const String newEmailsContentFolderName = 'new_emails'; static const String openedEmailContentFolderName = 'opened_email'; diff --git a/lib/features/push_notification/data/datasource/fcm_datasource.dart b/lib/features/push_notification/data/datasource/fcm_datasource.dart index 5ccdbb953..af9a9d47f 100644 --- a/lib/features/push_notification/data/datasource/fcm_datasource.dart +++ b/lib/features/push_notification/data/datasource/fcm_datasource.dart @@ -1,11 +1,13 @@ -import 'package:fcm/model/firebase_subscription.dart'; +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; import 'package:fcm/model/type_name.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/core/user_name.dart'; -import 'package:tmail_ui_user/features/push_notification/data/model/fcm_subscription.dart'; import 'package:tmail_ui_user/features/push_notification/domain/model/register_new_token_request.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/model/update_token_expired_time_request.dart'; abstract class FCMDatasource { Future storeStateToRefresh(AccountId accountId, UserName userName, TypeName typeName, jmap.State newState); @@ -14,13 +16,17 @@ abstract class FCMDatasource { Future deleteStateToRefresh(AccountId accountId, UserName userName, TypeName typeName); - Future storeSubscription(FCMSubscriptionCache fcmSubscriptionCache); + Future storeFirebaseRegistration(FirebaseRegistration firebaseRegistration); - Future getFirebaseSubscriptionByDeviceId(String deviceId); + Future getFirebaseRegistrationByDeviceId(DeviceClientId deviceId); - Future registerNewToken(RegisterNewTokenRequest newTokenRequest); + Future registerNewFirebaseRegistrationToken(RegisterNewTokenRequest newTokenRequest); - Future geSubscription(); + Future getStoredFirebaseRegistration(); - Future destroySubscription(String subscriptionId); + Future deleteFirebaseRegistrationCache(); + + Future destroyFirebaseRegistration(FirebaseRegistrationId registrationId); + + Future updateFirebaseRegistrationToken(UpdateTokenExpiredTimeRequest expiredTimeRequest); } \ No newline at end of file diff --git a/lib/features/push_notification/data/datasource_impl/cache_fcm_datasource_impl.dart b/lib/features/push_notification/data/datasource_impl/cache_fcm_datasource_impl.dart index 4ba5d92ca..b516744d7 100644 --- a/lib/features/push_notification/data/datasource_impl/cache_fcm_datasource_impl.dart +++ b/lib/features/push_notification/data/datasource_impl/cache_fcm_datasource_impl.dart @@ -1,12 +1,16 @@ -import 'package:fcm/model/firebase_subscription.dart'; +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; import 'package:fcm/model/type_name.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:tmail_ui_user/features/push_notification/data/datasource/fcm_datasource.dart'; +import 'package:tmail_ui_user/features/push_notification/data/extensions/firebase_registration_cache_extension.dart'; +import 'package:tmail_ui_user/features/push_notification/data/extensions/firebase_registration_extension.dart'; import 'package:tmail_ui_user/features/push_notification/data/local/fcm_cache_manager.dart'; -import 'package:tmail_ui_user/features/push_notification/data/model/fcm_subscription.dart'; import 'package:tmail_ui_user/features/push_notification/domain/model/register_new_token_request.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/model/update_token_expired_time_request.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; class CacheFCMDatasourceImpl extends FCMDatasource { @@ -38,31 +42,44 @@ class CacheFCMDatasourceImpl extends FCMDatasource { } @override - Future getFirebaseSubscriptionByDeviceId(String deviceId) { + Future getFirebaseRegistrationByDeviceId(DeviceClientId deviceId) { throw UnimplementedError(); } @override - Future registerNewToken(RegisterNewTokenRequest newTokenRequest) { + Future registerNewFirebaseRegistrationToken(RegisterNewTokenRequest newTokenRequest) { throw UnimplementedError(); } @override - Future storeSubscription(FCMSubscriptionCache fcmSubscriptionCache) { + Future storeFirebaseRegistration(FirebaseRegistration firebaseRegistration) { return Future.sync(() async { - return await _firebaseCacheManager.storeSubscription(fcmSubscriptionCache); + return await _firebaseCacheManager.storeFirebaseRegistration(firebaseRegistration.toFirebaseRegistrationCache()); }).catchError(_exceptionThrower.throwException); } @override - Future geSubscription() { + Future getStoredFirebaseRegistration() { return Future.sync(() async { - return await _firebaseCacheManager.getSubscription(); + final firebaseRegistrationCache = await _firebaseCacheManager.getStoredFirebaseRegistration(); + return firebaseRegistrationCache.toFirebaseRegistration(); }).catchError(_exceptionThrower.throwException); } @override - Future destroySubscription(String subscriptionId) { + Future destroyFirebaseRegistration(FirebaseRegistrationId registrationId) { throw UnimplementedError(); } + + @override + Future updateFirebaseRegistrationToken(UpdateTokenExpiredTimeRequest expiredTimeRequest) { + throw UnimplementedError(); + } + + @override + Future deleteFirebaseRegistrationCache() { + return Future.sync(() async { + return await _firebaseCacheManager.deleteFirebaseRegistration(); + }).catchError(_exceptionThrower.throwException); + } } \ No newline at end of file diff --git a/lib/features/push_notification/data/datasource_impl/fcm_datasource_impl.dart b/lib/features/push_notification/data/datasource_impl/fcm_datasource_impl.dart index 9d8e4741d..d8bbbeb79 100644 --- a/lib/features/push_notification/data/datasource_impl/fcm_datasource_impl.dart +++ b/lib/features/push_notification/data/datasource_impl/fcm_datasource_impl.dart @@ -1,13 +1,15 @@ -import 'package:fcm/model/firebase_subscription.dart'; +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; import 'package:fcm/model/type_name.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:tmail_ui_user/features/push_notification/data/datasource/fcm_datasource.dart'; -import 'package:tmail_ui_user/features/push_notification/data/model/fcm_subscription.dart'; import 'package:tmail_ui_user/features/push_notification/data/network/fcm_api.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/extensions/firebase_subscription_extension.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/extensions/firebase_registration_extension.dart'; import 'package:tmail_ui_user/features/push_notification/domain/model/register_new_token_request.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/model/update_token_expired_time_request.dart'; import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart'; class FcmDatasourceImpl extends FCMDatasource { @@ -18,9 +20,9 @@ class FcmDatasourceImpl extends FCMDatasource { FcmDatasourceImpl(this._fcmApi, this._exceptionThrower); @override - Future getFirebaseSubscriptionByDeviceId(String deviceId) { + Future getFirebaseRegistrationByDeviceId(DeviceClientId deviceId) { return Future.sync(() async { - return await _fcmApi.getFirebaseSubscriptionByDeviceId(deviceId); + return await _fcmApi.getFirebaseRegistrationByDeviceId(deviceId); }).catchError(_exceptionThrower.throwException); } @@ -40,27 +42,43 @@ class FcmDatasourceImpl extends FCMDatasource { } @override - Future registerNewToken(RegisterNewTokenRequest newTokenRequest) { + Future registerNewFirebaseRegistrationToken(RegisterNewTokenRequest newTokenRequest) { return Future.sync(() async { - final firebaseSubscription = await _fcmApi.registerNewToken(newTokenRequest); - return firebaseSubscription.fromDeviceId(newDeviceId: newTokenRequest.firebaseSubscription.deviceClientId); + final registrationCreated = await _fcmApi.registerNewFirebaseRegistrationToken(newTokenRequest); + return registrationCreated.syncProperties( + newDeviceId: newTokenRequest.firebaseRegistration.deviceClientId, + newFcmToken: newTokenRequest.firebaseRegistration.token, + newTypes: newTokenRequest.firebaseRegistration.types, + ); }).catchError(_exceptionThrower.throwException); } @override - Future storeSubscription(FCMSubscriptionCache fcmSubscriptionCache) { + Future storeFirebaseRegistration(FirebaseRegistration firebaseRegistration) { throw UnimplementedError(); } @override - Future geSubscription() { + Future getStoredFirebaseRegistration() { throw UnimplementedError(); } @override - Future destroySubscription(String subscriptionId) { + Future destroyFirebaseRegistration(FirebaseRegistrationId registrationId) { return Future.sync(() async { - return await _fcmApi.destroySubscription(subscriptionId); + return await _fcmApi.destroyFirebaseRegistration(registrationId); }).catchError(_exceptionThrower.throwException); } + + @override + Future updateFirebaseRegistrationToken(UpdateTokenExpiredTimeRequest expiredTimeRequest) { + return Future.sync(() async { + return await _fcmApi.updateFirebaseRegistrationToken(expiredTimeRequest); + }).catchError(_exceptionThrower.throwException); + } + + @override + Future deleteFirebaseRegistrationCache() { + throw UnimplementedError(); + } } \ No newline at end of file diff --git a/lib/features/push_notification/data/extensions/fcm_subscription_extensions.dart b/lib/features/push_notification/data/extensions/fcm_subscription_extensions.dart deleted file mode 100644 index 82c3de42c..000000000 --- a/lib/features/push_notification/data/extensions/fcm_subscription_extensions.dart +++ /dev/null @@ -1,10 +0,0 @@ - - -import 'package:tmail_ui_user/features/push_notification/data/model/fcm_subscription.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/model/fcm_subscription.dart'; - -extension FCMSubscriptionExtension on FCMSubscription { - FCMSubscriptionCache toFCMSubscriptionCache() { - return FCMSubscriptionCache(deviceId, subscriptionId); - } -} diff --git a/lib/features/push_notification/data/extensions/firebase_registration_cache_extension.dart b/lib/features/push_notification/data/extensions/firebase_registration_cache_extension.dart new file mode 100644 index 000000000..3602b9d1a --- /dev/null +++ b/lib/features/push_notification/data/extensions/firebase_registration_cache_extension.dart @@ -0,0 +1,20 @@ +import 'package:fcm/converter/device_client_id_nullable_converter.dart'; +import 'package:fcm/converter/fcm_token_nullable_converter.dart'; +import 'package:fcm/converter/firebase_registration_id_nullable_converter.dart'; +import 'package:fcm/converter/type_name_converter.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_expired_time.dart'; +import 'package:jmap_dart_client/jmap/core/utc_date.dart'; +import 'package:tmail_ui_user/features/push_notification/data/model/firebase_registration_cache.dart'; + +extension FirebaseRegistrationCacheExtension on FirebaseRegistrationCache { + FirebaseRegistration toFirebaseRegistration() { + return FirebaseRegistration( + id: const FirebaseRegistrationIdNullableConverter().fromJson(id), + token: const FcmTokenNullableConverter().fromJson(token), + deviceClientId: const DeviceClientIdNullableConverter().fromJson(deviceClientId), + expires: expires != null ? FirebaseRegistrationExpiredTime(UTCDate(expires!)) : null, + types: types?.map((type) => const TypeNameConverter().fromJson(type)).toList() + ); + } +} diff --git a/lib/features/push_notification/data/extensions/firebase_registration_extension.dart b/lib/features/push_notification/data/extensions/firebase_registration_extension.dart new file mode 100644 index 000000000..5dbb05ca2 --- /dev/null +++ b/lib/features/push_notification/data/extensions/firebase_registration_extension.dart @@ -0,0 +1,14 @@ +import 'package:fcm/model/firebase_registration.dart'; +import 'package:tmail_ui_user/features/push_notification/data/model/firebase_registration_cache.dart'; + +extension FirebaseRegistrationExtension on FirebaseRegistration { + FirebaseRegistrationCache toFirebaseRegistrationCache() { + return FirebaseRegistrationCache( + deviceClientId: deviceClientId!.value, + id: id?.id.value, + token: token?.value, + expires: expires?.value.value, + types: types?.map((type) => type.value).toList(), + ); + } +} diff --git a/lib/features/push_notification/data/local/fcm_cache_manager.dart b/lib/features/push_notification/data/local/fcm_cache_manager.dart index b916cb7eb..cadc2150b 100644 --- a/lib/features/push_notification/data/local/fcm_cache_manager.dart +++ b/lib/features/push_notification/data/local/fcm_cache_manager.dart @@ -3,17 +3,17 @@ import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:model/extensions/account_id_extensions.dart'; import 'package:tmail_ui_user/features/caching/clients/fcm_cache_client.dart'; -import 'package:tmail_ui_user/features/caching/clients/subscription_cache_client.dart'; +import 'package:tmail_ui_user/features/caching/clients/firebase_registration_cache_client.dart'; import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart'; -import 'package:tmail_ui_user/features/push_notification/data/model/fcm_subscription.dart'; +import 'package:tmail_ui_user/features/push_notification/data/model/firebase_registration_cache.dart'; import 'package:tmail_ui_user/features/push_notification/domain/exceptions/fcm_exception.dart'; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; class FCMCacheManager { final FcmCacheClient _fcmCacheClient; - final FCMSubscriptionCacheClient _fcmSubscriptionCacheClient; + final FirebaseRegistrationCacheClient _firebaseRegistrationCacheClient; - FCMCacheManager(this._fcmCacheClient,this._fcmSubscriptionCacheClient); + FCMCacheManager(this._fcmCacheClient,this._firebaseRegistrationCacheClient); Future storeStateToRefresh(AccountId accountId, UserName userName, TypeName typeName, jmap.State newState) { final stateKeyCache = TupleKey(typeName.value, accountId.asString, userName.value).encodeKey; @@ -43,17 +43,23 @@ class FCMCacheManager { return _fcmCacheClient.clearAllData(); } - Future storeSubscription(FCMSubscriptionCache fcmSubscriptionCache) { - return _fcmSubscriptionCacheClient.insertItem( - FCMSubscriptionCache.keyCacheValue, fcmSubscriptionCache); + Future storeFirebaseRegistration(FirebaseRegistrationCache firebaseRegistrationCache) { + return _firebaseRegistrationCacheClient.insertItem( + FirebaseRegistrationCache.keyCacheValue, + firebaseRegistrationCache + ); } - Future getSubscription() async { - final fcmSubscription = await _fcmSubscriptionCacheClient.getItem(FCMSubscriptionCache.keyCacheValue); - if (fcmSubscription == null) { - throw NotFoundSubscriptionException(); + Future getStoredFirebaseRegistration() async { + final firebaseRegistration = await _firebaseRegistrationCacheClient.getItem(FirebaseRegistrationCache.keyCacheValue); + if (firebaseRegistration == null) { + throw NotFoundFirebaseRegistrationCacheException(); } else { - return fcmSubscription; + return firebaseRegistration; } } + + Future deleteFirebaseRegistration() async { + await _firebaseRegistrationCacheClient.deleteItem(FirebaseRegistrationCache.keyCacheValue); + } } \ No newline at end of file diff --git a/lib/features/push_notification/data/model/fcm_subscription.dart b/lib/features/push_notification/data/model/fcm_subscription.dart deleted file mode 100644 index b7cb0aa26..000000000 --- a/lib/features/push_notification/data/model/fcm_subscription.dart +++ /dev/null @@ -1,23 +0,0 @@ - -import 'package:equatable/equatable.dart'; -import 'package:hive/hive.dart'; -import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart'; - -part 'fcm_subscription.g.dart'; - -@HiveType(typeId: CachingConstants.FCM_SUBSCRIPTION_HIVE_CACHE_IDENTITY) -class FCMSubscriptionCache extends HiveObject with EquatableMixin { - - static const String keyCacheValue = 'fcmSubscriptionCache'; - - @HiveField(0) - final String deviceId; - - @HiveField(1) - final String subscriptionId; - - FCMSubscriptionCache(this.deviceId, this.subscriptionId); - - @override - List get props => [deviceId, subscriptionId]; -} \ No newline at end of file diff --git a/lib/features/push_notification/data/model/firebase_registration_cache.dart b/lib/features/push_notification/data/model/firebase_registration_cache.dart new file mode 100644 index 000000000..f91c21b6b --- /dev/null +++ b/lib/features/push_notification/data/model/firebase_registration_cache.dart @@ -0,0 +1,44 @@ + +import 'package:equatable/equatable.dart'; +import 'package:hive/hive.dart'; +import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart'; + +part 'firebase_registration_cache.g.dart'; + +@HiveType(typeId: CachingConstants.FIREBASE_REGISTRATION_HIVE_CACHE_IDENTITY) +class FirebaseRegistrationCache extends HiveObject with EquatableMixin { + + static const String keyCacheValue = 'firebaseRegistrationCache'; + + @HiveField(0) + final String deviceClientId; + + @HiveField(1) + final String? id; + + @HiveField(2) + final String? token; + + @HiveField(3) + final DateTime? expires; + + @HiveField(4) + final List? types; + + FirebaseRegistrationCache({ + required this.deviceClientId, + this.id, + this.token, + this.expires, + this.types + }); + + @override + List get props => [ + deviceClientId, + id, + token, + expires, + types + ]; +} \ No newline at end of file diff --git a/lib/features/push_notification/data/network/fcm_api.dart b/lib/features/push_notification/data/network/fcm_api.dart index 3a78df6ca..a5339b477 100644 --- a/lib/features/push_notification/data/network/fcm_api.dart +++ b/lib/features/push_notification/data/network/fcm_api.dart @@ -1,16 +1,19 @@ -import 'package:fcm/method/set/firebase_subscription_set_method.dart'; -import 'package:fcm/method/set/firebase_subscription_set_response.dart'; -import 'package:fcm/method/get/firebase_subscription_get_method.dart'; -import 'package:fcm/method/get/firebase_subscription_get_response.dart'; -import 'package:fcm/model/firebase_capability.dart'; -import 'package:fcm/model/firebase_subscription.dart'; +import 'package:fcm/converter/firebase_registration_expired_time_nullable_converter.dart'; +import 'package:fcm/method/set/firebase_registration_set_method.dart'; +import 'package:fcm/method/set/firebase_registration_set_response.dart'; +import 'package:fcm/method/get/firebase_registration_get_method.dart'; +import 'package:fcm/method/get/firebase_registration_get_response.dart'; +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; import 'package:jmap_dart_client/http/http_client.dart'; -import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; -import 'package:jmap_dart_client/jmap/core/id.dart'; +import 'package:jmap_dart_client/jmap/core/patch_object.dart'; import 'package:jmap_dart_client/jmap/jmap_request.dart'; import 'package:tmail_ui_user/features/push_notification/domain/exceptions/fcm_exception.dart'; import 'package:tmail_ui_user/features/push_notification/domain/model/register_new_token_request.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/model/update_token_expired_time_request.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/utils/fcm_constants.dart'; class FcmApi { @@ -18,76 +21,105 @@ class FcmApi { FcmApi(this._httpClient); - Future getFirebaseSubscriptionByDeviceId(String deviceId) async { + Future getFirebaseRegistrationByDeviceId(DeviceClientId deviceId) async { final processingInvocation = ProcessingInvocation(); final requestBuilder = JmapRequestBuilder(_httpClient, processingInvocation); - final firebaseSubscriptionGetMethod = FirebaseSubscriptionGetMethod(); - final firebaseSubscriptionGetInvocation = requestBuilder.invocation(firebaseSubscriptionGetMethod); + final firebaseRegistrationGetMethod = FirebaseRegistrationGetMethod(); + final firebaseRegistrationGetInvocation = requestBuilder.invocation(firebaseRegistrationGetMethod); final response = await (requestBuilder - ..usings(firebaseSubscriptionGetMethod.requiredCapabilities)) + ..usings(firebaseRegistrationGetMethod.requiredCapabilities)) .build() .execute(); - final getResponse = response.parse( - firebaseSubscriptionGetInvocation.methodCallId, - FirebaseSubscriptionGetResponse.deserialize); + final getResponse = response.parse( + firebaseRegistrationGetInvocation.methodCallId, + FirebaseRegistrationGetResponse.deserialize); - final matchedFirebaseSubscription = getResponse?.list - .where((fcmSub) => fcmSub.deviceClientId?.value == deviceId) + final matchedFirebaseRegistration = getResponse?.list + .where((fcmSub) => fcmSub.deviceClientId == deviceId) .toList(); - if (matchedFirebaseSubscription?.isNotEmpty == true) { - return matchedFirebaseSubscription!.first; + if (matchedFirebaseRegistration?.isNotEmpty == true) { + return matchedFirebaseRegistration!.first; } else { - throw NotFoundFirebaseSubscriptionException(); + throw NotFoundFirebaseRegistrationForDeviceException(); } } - Future registerNewToken(RegisterNewTokenRequest newTokenRequest) async { + Future registerNewFirebaseRegistrationToken(RegisterNewTokenRequest newTokenRequest) async { final processingInvocation = ProcessingInvocation(); final requestBuilder = JmapRequestBuilder(_httpClient, processingInvocation); - final firebaseSubscriptionSetMethod = FirebaseSubscriptionSetMethod() + final firebaseRegistrationSetMethod = FirebaseRegistrationSetMethod() ..addCreate( newTokenRequest.createRequestId, - newTokenRequest.firebaseSubscription + newTokenRequest.firebaseRegistration ); - final firebaseSubscriptionSetInvocation = requestBuilder.invocation(firebaseSubscriptionSetMethod); + final firebaseRegistrationSetInvocation = requestBuilder.invocation(firebaseRegistrationSetMethod); final response = await (requestBuilder - ..usings(firebaseSubscriptionSetMethod.requiredCapabilities)) + ..usings(firebaseRegistrationSetMethod.requiredCapabilities)) .build() .execute(); - final firebaseSubscriptionSetResponse = response.parse( - firebaseSubscriptionSetInvocation.methodCallId, - FirebaseSubscriptionSetResponse.deserialize); + final firebaseRegistrationSetResponse = response.parse( + firebaseRegistrationSetInvocation.methodCallId, + FirebaseRegistrationSetResponse.deserialize); - return firebaseSubscriptionSetResponse!.created![newTokenRequest.createRequestId]!; + final firebaseRegistration = firebaseRegistrationSetResponse?.created?[newTokenRequest.createRequestId]; + if (firebaseRegistration != null) { + return firebaseRegistration; + } else { + throw NotFoundFirebaseRegistrationCreatedException(); + } } - Future destroySubscription(String subscriptionId) async { + Future destroyFirebaseRegistration(FirebaseRegistrationId registrationId) async { final processingInvocation = ProcessingInvocation(); final requestBuilder = JmapRequestBuilder(_httpClient, processingInvocation); - final firebaseSubscriptionSetMethod = FirebaseSubscriptionSetMethod()..addDestroy({Id(subscriptionId)}); - final firebaseSubscriptionSetInvocation = requestBuilder.invocation(firebaseSubscriptionSetMethod); + final firebaseRegistrationSetMethod = FirebaseRegistrationSetMethod()..addDestroy({registrationId.id}); + final firebaseRegistrationSetInvocation = requestBuilder.invocation(firebaseRegistrationSetMethod); final response = await (requestBuilder - ..usings({ - CapabilityIdentifier.jmapCore, - FirebaseCapability.fcmIdentifier, - })) + ..usings(firebaseRegistrationSetMethod.requiredCapabilities)) .build() .execute(); - final firebaseSubscriptionSetResponse = response.parse( - firebaseSubscriptionSetInvocation.methodCallId, - FirebaseSubscriptionSetResponse.deserialize); + final firebaseRegistrationSetResponse = response.parse( + firebaseRegistrationSetInvocation.methodCallId, + FirebaseRegistrationSetResponse.deserialize); - return Future.sync(() async { - return firebaseSubscriptionSetResponse?.destroyed?.contains(Id(subscriptionId)) == true; - }).catchError((error) { - throw error; - }); + if (firebaseRegistrationSetResponse?.destroyed?.contains(registrationId.id) == true) { + return; + } else { + throw NotFoundFirebaseRegistrationDestroyedException(); + } + } + + Future updateFirebaseRegistrationToken(UpdateTokenExpiredTimeRequest expiredTimeRequest) async { + final processingInvocation = ProcessingInvocation(); + final requestBuilder = JmapRequestBuilder(_httpClient, processingInvocation); + + final firebaseRegistrationSetMethod = FirebaseRegistrationSetMethod() + ..addUpdates({ + expiredTimeRequest.firebaseRegistrationId.id: PatchObject({ + FcmConstants.firebaseRegistrationExpiredTimeProperty: const FirebaseRegistrationExpiredTimeNullableConverter().toJson(expiredTimeRequest.firebaseRegistrationExpiredTime) + }) + }); + final firebaseRegistrationSetInvocation = requestBuilder.invocation(firebaseRegistrationSetMethod); + final response = await (requestBuilder + ..usings(firebaseRegistrationSetMethod.requiredCapabilities)) + .build() + .execute(); + + final firebaseRegistrationSetResponse = response.parse( + firebaseRegistrationSetInvocation.methodCallId, + FirebaseRegistrationSetResponse.deserialize); + + if (firebaseRegistrationSetResponse?.updated?.containsKey(expiredTimeRequest.firebaseRegistrationId.id) == true) { + return; + } else { + throw NotFoundFirebaseRegistrationUpdatedException(); + } } } \ No newline at end of file diff --git a/lib/features/push_notification/data/repository/fcm_repository_impl.dart b/lib/features/push_notification/data/repository/fcm_repository_impl.dart index 338e909bb..8bf31af42 100644 --- a/lib/features/push_notification/data/repository/fcm_repository_impl.dart +++ b/lib/features/push_notification/data/repository/fcm_repository_impl.dart @@ -1,6 +1,8 @@ import 'package:core/data/model/source_type/data_source_type.dart'; import 'package:core/utils/app_logger.dart'; -import 'package:fcm/model/firebase_subscription.dart'; +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; import 'package:fcm/model/type_name.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/properties/properties.dart'; @@ -15,10 +17,9 @@ import 'package:model/extensions/presentation_mailbox_extension.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:tmail_ui_user/features/mailbox/data/datasource/mailbox_datasource.dart'; import 'package:tmail_ui_user/features/push_notification/data/datasource/fcm_datasource.dart'; -import 'package:tmail_ui_user/features/push_notification/data/extensions/fcm_subscription_extensions.dart'; import 'package:tmail_ui_user/features/push_notification/domain/exceptions/fcm_exception.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/model/fcm_subscription.dart'; import 'package:tmail_ui_user/features/push_notification/domain/model/register_new_token_request.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/model/update_token_expired_time_request.dart'; import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; import 'package:tmail_ui_user/features/push_notification/domain/utils/fcm_constants.dart'; import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart'; @@ -94,29 +95,28 @@ class FCMRepositoryImpl extends FCMRepository { } @override - Future getFirebaseSubscriptionByDeviceId(String deviceId) { - return _fcmDatasource[DataSourceType.network]!.getFirebaseSubscriptionByDeviceId(deviceId); + Future getFirebaseRegistrationByDeviceId(DeviceClientId deviceId) { + return _fcmDatasource[DataSourceType.network]!.getFirebaseRegistrationByDeviceId(deviceId); } @override - Future registerNewToken(RegisterNewTokenRequest newTokenRequest) { - return _fcmDatasource[DataSourceType.network]!.registerNewToken(newTokenRequest); + Future registerNewFirebaseRegistrationToken(RegisterNewTokenRequest newTokenRequest) { + return _fcmDatasource[DataSourceType.network]!.registerNewFirebaseRegistrationToken(newTokenRequest); } @override - Future getSubscription() async { - final fcmSubScription = await _fcmDatasource[DataSourceType.local]!.geSubscription(); - return FCMSubscription(fcmSubScription.deviceId, fcmSubScription.subscriptionId); + Future getStoredFirebaseRegistration() { + return _fcmDatasource[DataSourceType.local]!.getStoredFirebaseRegistration(); } @override - Future storeSubscription(FCMSubscription fcmSubscription) { - return _fcmDatasource[DataSourceType.local]!.storeSubscription(fcmSubscription.toFCMSubscriptionCache()); + Future storeFirebaseRegistration(FirebaseRegistration firebaseRegistration) { + return _fcmDatasource[DataSourceType.local]!.storeFirebaseRegistration(firebaseRegistration); } @override - Future destroySubscription(String subscriptionId) { - return _fcmDatasource[DataSourceType.network]!.destroySubscription(subscriptionId); + Future destroyFirebaseRegistration(FirebaseRegistrationId registrationId) { + return _fcmDatasource[DataSourceType.network]!.destroyFirebaseRegistration(registrationId); } @override @@ -127,7 +127,7 @@ class FCMRepositoryImpl extends FCMRepository { .where((presentationMailbox) => presentationMailbox.pushNotificationDeactivated) .toList(); log('FCMRepositoryImpl::getMailboxesNotPutNotifications():mailboxesCacheNotPutNotifications: $mailboxesCacheNotPutNotifications'); - if (mailboxesCacheNotPutNotifications.isNotEmpty && mailboxesCacheNotPutNotifications.length == FcmConstants.mailboxRuleAllowPushNotifications.length) { + if (mailboxesCacheNotPutNotifications.isNotEmpty && mailboxesCacheNotPutNotifications.length == FcmConstants.mailboxRuleDoNotAllowPushNotifications.length) { return mailboxesCacheNotPutNotifications; } else { final mailboxResponse = await _mapMailboxDataSource[DataSourceType.network]!.getAllMailbox(session, accountId); @@ -217,4 +217,14 @@ class FCMRepositoryImpl extends FCMRepository { throw NotFoundNewReceiveEmailException(); } } + + @override + Future updateFirebaseRegistrationToken(UpdateTokenExpiredTimeRequest expiredTimeRequest) { + return _fcmDatasource[DataSourceType.network]!.updateFirebaseRegistrationToken(expiredTimeRequest); + } + + @override + Future deleteFirebaseRegistrationCache() { + return _fcmDatasource[DataSourceType.local]!.deleteFirebaseRegistrationCache(); + } } \ No newline at end of file diff --git a/lib/features/push_notification/domain/exceptions/fcm_exception.dart b/lib/features/push_notification/domain/exceptions/fcm_exception.dart index 4be012173..9a6377f22 100644 --- a/lib/features/push_notification/domain/exceptions/fcm_exception.dart +++ b/lib/features/push_notification/domain/exceptions/fcm_exception.dart @@ -6,12 +6,18 @@ class NotFoundStateToRefreshException implements Exception {} class NotFoundEmailDeliveryStateException implements Exception {} -class NotFoundFirebaseSubscriptionException implements Exception {} +class NotFoundFirebaseRegistrationForDeviceException implements Exception {} -class NotFoundSubscriptionException implements Exception {} +class NotFoundFirebaseRegistrationCacheException implements Exception {} class NotFoundEmailStateException implements Exception {} class NotFoundNewReceiveEmailException implements Exception {} -class EmailStateNoChangeException implements Exception {} \ No newline at end of file +class EmailStateNoChangeException implements Exception {} + +class NotFoundFirebaseRegistrationCreatedException implements Exception {} + +class NotFoundFirebaseRegistrationUpdatedException implements Exception {} + +class NotFoundFirebaseRegistrationDestroyedException implements Exception {} \ No newline at end of file diff --git a/lib/features/push_notification/domain/extensions/firebase_registration_extension.dart b/lib/features/push_notification/domain/extensions/firebase_registration_extension.dart new file mode 100644 index 000000000..8726d072a --- /dev/null +++ b/lib/features/push_notification/domain/extensions/firebase_registration_extension.dart @@ -0,0 +1,22 @@ + +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/fcm_token.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/type_name.dart'; + +extension FirebaseRegistrationExtension on FirebaseRegistration { + + FirebaseRegistration syncProperties({ + DeviceClientId? newDeviceId, + FcmToken? newFcmToken, + List? newTypes, + }) { + return FirebaseRegistration( + id: id, + token: newFcmToken ?? token, + deviceClientId: newDeviceId ?? deviceClientId, + expires: expires, + types: newTypes ?? types + ); + } +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/extensions/firebase_subscription_extension.dart b/lib/features/push_notification/domain/extensions/firebase_subscription_extension.dart deleted file mode 100644 index 37effedd5..000000000 --- a/lib/features/push_notification/domain/extensions/firebase_subscription_extension.dart +++ /dev/null @@ -1,16 +0,0 @@ - -import 'package:fcm/model/device_client_id.dart'; -import 'package:fcm/model/firebase_subscription.dart'; - -extension FirebaseSubscriptionExtension on FirebaseSubscription { - - FirebaseSubscription fromDeviceId({DeviceClientId? newDeviceId}) { - return FirebaseSubscription( - id: id, - token: token, - deviceClientId: newDeviceId ?? deviceClientId, - expires: expires, - types: types - ); - } -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/model/fcm_subscription.dart b/lib/features/push_notification/domain/model/fcm_subscription.dart deleted file mode 100644 index 0a5840a15..000000000 --- a/lib/features/push_notification/domain/model/fcm_subscription.dart +++ /dev/null @@ -1,16 +0,0 @@ - -import 'package:equatable/equatable.dart'; - -class FCMSubscription with EquatableMixin { - - final String deviceId; - final String subscriptionId; - - FCMSubscription(this.deviceId, this.subscriptionId); - - @override - List get props => [ - deviceId, - subscriptionId - ]; -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/model/register_new_token_request.dart b/lib/features/push_notification/domain/model/register_new_token_request.dart index ff79e02c5..82378d5cd 100644 --- a/lib/features/push_notification/domain/model/register_new_token_request.dart +++ b/lib/features/push_notification/domain/model/register_new_token_request.dart @@ -1,18 +1,18 @@ import 'package:equatable/equatable.dart'; -import 'package:fcm/model/firebase_subscription.dart'; +import 'package:fcm/model/firebase_registration.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; class RegisterNewTokenRequest with EquatableMixin { final Id createRequestId; - final FirebaseSubscription firebaseSubscription; + final FirebaseRegistration firebaseRegistration; - RegisterNewTokenRequest(this.createRequestId, this.firebaseSubscription); + RegisterNewTokenRequest(this.createRequestId, this.firebaseRegistration); @override List get props => [ createRequestId, - firebaseSubscription + firebaseRegistration ]; } \ No newline at end of file diff --git a/lib/features/push_notification/domain/model/update_token_expired_time_request.dart b/lib/features/push_notification/domain/model/update_token_expired_time_request.dart new file mode 100644 index 000000000..06671c345 --- /dev/null +++ b/lib/features/push_notification/domain/model/update_token_expired_time_request.dart @@ -0,0 +1,21 @@ + +import 'package:equatable/equatable.dart'; +import 'package:fcm/model/firebase_registration_expired_time.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; + +class UpdateTokenExpiredTimeRequest with EquatableMixin { + + final FirebaseRegistrationId firebaseRegistrationId; + final FirebaseRegistrationExpiredTime firebaseRegistrationExpiredTime; + + UpdateTokenExpiredTimeRequest( + this.firebaseRegistrationId, + this.firebaseRegistrationExpiredTime + ); + + @override + List get props => [ + firebaseRegistrationId, + firebaseRegistrationExpiredTime + ]; +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/repository/fcm_repository.dart b/lib/features/push_notification/domain/repository/fcm_repository.dart index bee2561ed..48830374a 100644 --- a/lib/features/push_notification/domain/repository/fcm_repository.dart +++ b/lib/features/push_notification/domain/repository/fcm_repository.dart @@ -1,4 +1,6 @@ -import 'package:fcm/model/firebase_subscription.dart'; +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; import 'package:fcm/model/type_name.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/core/properties/properties.dart'; @@ -6,8 +8,8 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart'; import 'package:jmap_dart_client/jmap/core/user_name.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/model/fcm_subscription.dart'; import 'package:tmail_ui_user/features/push_notification/domain/model/register_new_token_request.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/model/update_token_expired_time_request.dart'; import 'package:tmail_ui_user/features/thread/domain/model/email_response.dart'; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; @@ -28,15 +30,19 @@ abstract class FCMRepository { Future deleteStateToRefresh(AccountId accountId, UserName userName, TypeName typeName); - Future storeSubscription(FCMSubscription fcmSubscription); + Future storeFirebaseRegistration(FirebaseRegistration firebaseRegistration); - Future getFirebaseSubscriptionByDeviceId(String deviceId); + Future getFirebaseRegistrationByDeviceId(DeviceClientId deviceId); - Future registerNewToken(RegisterNewTokenRequest newTokenRequest); + Future registerNewFirebaseRegistrationToken(RegisterNewTokenRequest newTokenRequest); - Future getSubscription(); + Future getStoredFirebaseRegistration(); - Future destroySubscription(String subscriptionId); + Future deleteFirebaseRegistrationCache(); + + Future destroyFirebaseRegistration(FirebaseRegistrationId registrationId); + + Future updateFirebaseRegistrationToken(UpdateTokenExpiredTimeRequest expiredTimeRequest); Future> getMailboxesNotPutNotifications(Session session, AccountId accountId); diff --git a/lib/features/push_notification/domain/state/delete_firebase_registration_cache_state.dart b/lib/features/push_notification/domain/state/delete_firebase_registration_cache_state.dart new file mode 100644 index 000000000..ea5490d46 --- /dev/null +++ b/lib/features/push_notification/domain/state/delete_firebase_registration_cache_state.dart @@ -0,0 +1,12 @@ + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class DeleteFirebaseRegistrationCacheLoading extends LoadingState {} + +class DeleteFirebaseRegistrationCacheSuccess extends UIState {} + +class DeleteFirebaseRegistrationCacheFailure extends FeatureFailure { + + DeleteFirebaseRegistrationCacheFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/destroy_firebase_registration_state.dart b/lib/features/push_notification/domain/state/destroy_firebase_registration_state.dart new file mode 100644 index 000000000..d661ea4c8 --- /dev/null +++ b/lib/features/push_notification/domain/state/destroy_firebase_registration_state.dart @@ -0,0 +1,11 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class DestroyFirebaseRegistrationLoading extends LoadingState {} + +class DestroyFirebaseRegistrationSuccess extends UIState {} + +class DestroyFirebaseRegistrationFailure extends FeatureFailure { + + DestroyFirebaseRegistrationFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/destroy_subscription_state.dart b/lib/features/push_notification/domain/state/destroy_subscription_state.dart deleted file mode 100644 index 6868ef40b..000000000 --- a/lib/features/push_notification/domain/state/destroy_subscription_state.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; - -class DestroySubscriptionLoading extends UIState {} - -class DestroySubscriptionSuccess extends UIState { - - final bool destroyedSubscription; - - DestroySubscriptionSuccess(this.destroyedSubscription); - - @override - List get props => [destroyedSubscription]; -} - -class DestroySubscriptionFailure extends FeatureFailure { - - DestroySubscriptionFailure(dynamic exception) : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/get_fcm_subscription_local.dart b/lib/features/push_notification/domain/state/get_fcm_subscription_local.dart deleted file mode 100644 index 431783a0f..000000000 --- a/lib/features/push_notification/domain/state/get_fcm_subscription_local.dart +++ /dev/null @@ -1,21 +0,0 @@ - -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/model/fcm_subscription.dart'; - -class GetFCMSubscriptionLocalLoading extends UIState {} - -class GetFCMSubscriptionLocalSuccess extends UIState { - - final FCMSubscription fcmSubscription; - - GetFCMSubscriptionLocalSuccess(this.fcmSubscription); - - @override - List get props => [fcmSubscription]; -} - -class GetFCMSubscriptionLocalFailure extends FeatureFailure { - - GetFCMSubscriptionLocalFailure(dynamic exception) : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/get_firebase_registration_by_device_id_state.dart b/lib/features/push_notification/domain/state/get_firebase_registration_by_device_id_state.dart new file mode 100644 index 000000000..048a68103 --- /dev/null +++ b/lib/features/push_notification/domain/state/get_firebase_registration_by_device_id_state.dart @@ -0,0 +1,27 @@ + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:fcm/model/fcm_token.dart'; +import 'package:fcm/model/firebase_registration.dart'; + +class GetFirebaseRegistrationByDeviceIdLoading extends LoadingState {} + +class GetFirebaseRegistrationByDeviceIdSuccess extends UIState { + + final FirebaseRegistration firebaseRegistration; + final FcmToken? newFcmToken; + + GetFirebaseRegistrationByDeviceIdSuccess(this.firebaseRegistration, this.newFcmToken); + + @override + List get props => [firebaseRegistration, newFcmToken]; +} + +class GetFirebaseRegistrationByDeviceIdFailure extends FeatureFailure { + final FcmToken? newFcmToken; + + GetFirebaseRegistrationByDeviceIdFailure(dynamic exception, this.newFcmToken) : super(exception: exception); + + @override + List get props => [newFcmToken, ...super.props]; +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/get_firebase_subscription_state.dart b/lib/features/push_notification/domain/state/get_firebase_subscription_state.dart deleted file mode 100644 index c9d714d8d..000000000 --- a/lib/features/push_notification/domain/state/get_firebase_subscription_state.dart +++ /dev/null @@ -1,21 +0,0 @@ - -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:fcm/model/firebase_subscription.dart'; - -class GetFirebaseSubscriptionLoading extends UIState {} - -class GetFirebaseSubscriptionSuccess extends UIState { - - final FirebaseSubscription firebaseSubscription; - - GetFirebaseSubscriptionSuccess(this.firebaseSubscription); - - @override - List get props => [firebaseSubscription]; -} - -class GetFirebaseSubscriptionFailure extends FeatureFailure { - - GetFirebaseSubscriptionFailure(dynamic exception) : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/get_stored_firebase_registration_state.dart b/lib/features/push_notification/domain/state/get_stored_firebase_registration_state.dart new file mode 100644 index 000000000..4ae0cb41f --- /dev/null +++ b/lib/features/push_notification/domain/state/get_stored_firebase_registration_state.dart @@ -0,0 +1,21 @@ + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:fcm/model/firebase_registration.dart'; + +class GetStoredFirebaseRegistrationLoading extends LoadingState {} + +class GetStoredFirebaseRegistrationSuccess extends UIState { + + final FirebaseRegistration firebaseRegistration; + + GetStoredFirebaseRegistrationSuccess(this.firebaseRegistration); + + @override + List get props => [firebaseRegistration]; +} + +class GetStoredFirebaseRegistrationFailure extends FeatureFailure { + + GetStoredFirebaseRegistrationFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/register_new_firebase_registration_token_state.dart b/lib/features/push_notification/domain/state/register_new_firebase_registration_token_state.dart new file mode 100644 index 000000000..0a265d142 --- /dev/null +++ b/lib/features/push_notification/domain/state/register_new_firebase_registration_token_state.dart @@ -0,0 +1,21 @@ + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:fcm/model/firebase_registration.dart'; + +class RegisterNewFirebaseRegistrationTokenLoading extends LoadingState {} + +class RegisterNewFirebaseRegistrationTokenSuccess extends UIState { + + final FirebaseRegistration firebaseRegistration; + + RegisterNewFirebaseRegistrationTokenSuccess(this.firebaseRegistration); + + @override + List get props => [firebaseRegistration]; +} + +class RegisterNewFirebaseRegistrationTokenFailure extends FeatureFailure { + + RegisterNewFirebaseRegistrationTokenFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/register_new_token_state.dart b/lib/features/push_notification/domain/state/register_new_token_state.dart deleted file mode 100644 index 522ddda99..000000000 --- a/lib/features/push_notification/domain/state/register_new_token_state.dart +++ /dev/null @@ -1,21 +0,0 @@ - -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:fcm/model/firebase_subscription.dart'; - -class RegisterNewTokenLoading extends UIState {} - -class RegisterNewTokenSuccess extends UIState { - - final FirebaseSubscription firebaseSubscription; - - RegisterNewTokenSuccess(this.firebaseSubscription); - - @override - List get props => [firebaseSubscription]; -} - -class RegisterNewTokenFailure extends FeatureFailure { - - RegisterNewTokenFailure(dynamic exception) : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/store_firebase_registration_state.dart b/lib/features/push_notification/domain/state/store_firebase_registration_state.dart new file mode 100644 index 000000000..fe164602c --- /dev/null +++ b/lib/features/push_notification/domain/state/store_firebase_registration_state.dart @@ -0,0 +1,12 @@ + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class StoreFirebaseRegistrationLoading extends LoadingState {} + +class StoreFirebaseRegistrationSuccess extends UIState {} + +class StoreFirebaseRegistrationFailure extends FeatureFailure { + + StoreFirebaseRegistrationFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/store_subscription_state.dart b/lib/features/push_notification/domain/state/store_subscription_state.dart deleted file mode 100644 index de362f5f0..000000000 --- a/lib/features/push_notification/domain/state/store_subscription_state.dart +++ /dev/null @@ -1,12 +0,0 @@ - -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; - -class StoreSubscriptionLoading extends UIState {} - -class StoreSubscriptionSuccess extends UIState {} - -class StoreSubscriptionFailure extends FeatureFailure { - - StoreSubscriptionFailure(dynamic exception) : super(exception: exception); -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/state/update_firebase_registration_token_state.dart b/lib/features/push_notification/domain/state/update_firebase_registration_token_state.dart new file mode 100644 index 000000000..10a52a26c --- /dev/null +++ b/lib/features/push_notification/domain/state/update_firebase_registration_token_state.dart @@ -0,0 +1,12 @@ + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; + +class UpdateFirebaseRegistrationTokenLoading extends LoadingState {} + +class UpdateFirebaseRegistrationTokenSuccess extends UIState {} + +class UpdateFirebaseRegistrationTokenFailure extends FeatureFailure { + + UpdateFirebaseRegistrationTokenFailure(dynamic exception) : super(exception: exception); +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/delete_firebase_registration_cache_interactor.dart b/lib/features/push_notification/domain/usecases/delete_firebase_registration_cache_interactor.dart new file mode 100644 index 000000000..472059e44 --- /dev/null +++ b/lib/features/push_notification/domain/usecases/delete_firebase_registration_cache_interactor.dart @@ -0,0 +1,21 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/delete_firebase_registration_cache_state.dart'; + +class DeleteFirebaseRegistrationCacheInteractor { + final FCMRepository _fcmRepository; + + DeleteFirebaseRegistrationCacheInteractor(this._fcmRepository); + + Stream> execute() async* { + try { + yield Right(DeleteFirebaseRegistrationCacheLoading()); + await _fcmRepository.getStoredFirebaseRegistration(); + yield Right(DeleteFirebaseRegistrationCacheSuccess()); + } catch (e) { + yield Left(DeleteFirebaseRegistrationCacheFailure(e)); + } + } +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/destroy_firebase_registration_interactor.dart b/lib/features/push_notification/domain/usecases/destroy_firebase_registration_interactor.dart new file mode 100644 index 000000000..3178735b6 --- /dev/null +++ b/lib/features/push_notification/domain/usecases/destroy_firebase_registration_interactor.dart @@ -0,0 +1,23 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:fcm/model/firebase_registration_id.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/destroy_firebase_registration_state.dart'; + +class DestroyFirebaseRegistrationInteractor { + + final FCMRepository _fcmRepository; + + DestroyFirebaseRegistrationInteractor(this._fcmRepository); + + Stream> execute(FirebaseRegistrationId registrationId) async* { + try { + yield Right(DestroyFirebaseRegistrationLoading()); + await _fcmRepository.destroyFirebaseRegistration(registrationId); + yield Right(DestroyFirebaseRegistrationSuccess()); + } catch (e) { + yield Left(DestroyFirebaseRegistrationFailure(e)); + } + } +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/destroy_subscription_interactor.dart b/lib/features/push_notification/domain/usecases/destroy_subscription_interactor.dart deleted file mode 100644 index 69022d0e2..000000000 --- a/lib/features/push_notification/domain/usecases/destroy_subscription_interactor.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:dartz/dartz.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/destroy_subscription_state.dart'; - -class DestroySubscriptionInteractor { - - final FCMRepository _fcmRepository; - - DestroySubscriptionInteractor(this._fcmRepository); - - Stream> execute(String subscriptionId) async* { - try { - yield Right(DestroySubscriptionLoading()); - final destroyedSubscription = await _fcmRepository.destroySubscription(subscriptionId); - yield Right(DestroySubscriptionSuccess(destroyedSubscription)); - } catch (e) { - yield Left(DestroySubscriptionFailure(e)); - } - } -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/get_fcm_subscription_local_interactor.dart b/lib/features/push_notification/domain/usecases/get_fcm_subscription_local_interactor.dart deleted file mode 100644 index 43f9e2036..000000000 --- a/lib/features/push_notification/domain/usecases/get_fcm_subscription_local_interactor.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:dartz/dartz.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/get_fcm_subscription_local.dart'; - -class GetFCMSubscriptionLocalInteractor { - final FCMRepository _fcmRepository; - - GetFCMSubscriptionLocalInteractor(this._fcmRepository); - - Stream> execute() async* { - try { - yield Right(GetFCMSubscriptionLocalLoading()); - final subscription = await _fcmRepository.getSubscription(); - yield Right(GetFCMSubscriptionLocalSuccess(subscription)); - } catch (e) { - yield Left(GetFCMSubscriptionLocalFailure(e)); - } - } -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/get_firebase_registration_by_device_id_interactor.dart b/lib/features/push_notification/domain/usecases/get_firebase_registration_by_device_id_interactor.dart new file mode 100644 index 000000000..a1bf1c684 --- /dev/null +++ b/lib/features/push_notification/domain/usecases/get_firebase_registration_by_device_id_interactor.dart @@ -0,0 +1,25 @@ + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:fcm/model/device_client_id.dart'; +import 'package:fcm/model/fcm_token.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/get_firebase_registration_by_device_id_state.dart'; + +class GetFirebaseRegistrationByDeviceIdInteractor { + + final FCMRepository _fcmRepository; + + GetFirebaseRegistrationByDeviceIdInteractor(this._fcmRepository); + + Stream> execute({required DeviceClientId deviceClientId, FcmToken? newFcmToken}) async* { + try { + yield Right(GetFirebaseRegistrationByDeviceIdLoading()); + final firebaseRegistration = await _fcmRepository.getFirebaseRegistrationByDeviceId(deviceClientId); + yield Right(GetFirebaseRegistrationByDeviceIdSuccess(firebaseRegistration, newFcmToken)); + } catch (e) { + yield Left(GetFirebaseRegistrationByDeviceIdFailure(e, newFcmToken)); + } + } +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/get_firebase_subscription_interactor.dart b/lib/features/push_notification/domain/usecases/get_firebase_subscription_interactor.dart deleted file mode 100644 index b9bb029de..000000000 --- a/lib/features/push_notification/domain/usecases/get_firebase_subscription_interactor.dart +++ /dev/null @@ -1,23 +0,0 @@ - -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:dartz/dartz.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/get_firebase_subscription_state.dart'; - -class GetFirebaseSubscriptionInteractor { - - final FCMRepository _fcmRepository; - - GetFirebaseSubscriptionInteractor(this._fcmRepository); - - Stream> execute(String deviceId) async* { - try { - yield Right(GetFirebaseSubscriptionLoading()); - final firebaseSubscription = await _fcmRepository.getFirebaseSubscriptionByDeviceId(deviceId); - yield Right(GetFirebaseSubscriptionSuccess(firebaseSubscription)); - } catch (e) { - yield Left(GetFirebaseSubscriptionFailure(e)); - } - } -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/get_stored_firebase_registration_interactor.dart b/lib/features/push_notification/domain/usecases/get_stored_firebase_registration_interactor.dart new file mode 100644 index 000000000..6d920c51b --- /dev/null +++ b/lib/features/push_notification/domain/usecases/get_stored_firebase_registration_interactor.dart @@ -0,0 +1,21 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/get_stored_firebase_registration_state.dart'; + +class GetStoredFirebaseRegistrationInteractor { + final FCMRepository _fcmRepository; + + GetStoredFirebaseRegistrationInteractor(this._fcmRepository); + + Stream> execute() async* { + try { + yield Right(GetStoredFirebaseRegistrationLoading()); + final registration = await _fcmRepository.getStoredFirebaseRegistration(); + yield Right(GetStoredFirebaseRegistrationSuccess(registration)); + } catch (e) { + yield Left(GetStoredFirebaseRegistrationFailure(e)); + } + } +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/register_new_token_interactor.dart b/lib/features/push_notification/domain/usecases/register_new_firebase_registration_token_interactor.dart similarity index 50% rename from lib/features/push_notification/domain/usecases/register_new_token_interactor.dart rename to lib/features/push_notification/domain/usecases/register_new_firebase_registration_token_interactor.dart index 88b714533..3e264a94e 100644 --- a/lib/features/push_notification/domain/usecases/register_new_token_interactor.dart +++ b/lib/features/push_notification/domain/usecases/register_new_firebase_registration_token_interactor.dart @@ -4,21 +4,21 @@ import 'package:core/presentation/state/success.dart'; import 'package:dartz/dartz.dart'; import 'package:tmail_ui_user/features/push_notification/domain/model/register_new_token_request.dart'; import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/register_new_token_state.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/register_new_firebase_registration_token_state.dart'; -class RegisterNewTokenInteractor { +class RegisterNewFirebaseRegistrationTokenInteractor { final FCMRepository _fcmRepository; - RegisterNewTokenInteractor(this._fcmRepository); + RegisterNewFirebaseRegistrationTokenInteractor(this._fcmRepository); Stream> execute(RegisterNewTokenRequest newTokenRequest) async* { try { - yield Right(RegisterNewTokenLoading()); - final firebaseSubscription = await _fcmRepository.registerNewToken(newTokenRequest); - yield Right(RegisterNewTokenSuccess(firebaseSubscription)); + yield Right(RegisterNewFirebaseRegistrationTokenLoading()); + final firebaseRegistration = await _fcmRepository.registerNewFirebaseRegistrationToken(newTokenRequest); + yield Right(RegisterNewFirebaseRegistrationTokenSuccess(firebaseRegistration)); } catch (e) { - yield Left(RegisterNewTokenFailure(e)); + yield Left(RegisterNewFirebaseRegistrationTokenFailure(e)); } } } \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/store_firebase_registration_interator.dart b/lib/features/push_notification/domain/usecases/store_firebase_registration_interator.dart new file mode 100644 index 000000000..24135760c --- /dev/null +++ b/lib/features/push_notification/domain/usecases/store_firebase_registration_interator.dart @@ -0,0 +1,22 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/store_firebase_registration_state.dart'; + +class StoreFirebaseRegistrationInteractor { + final FCMRepository _fcmRepository; + + StoreFirebaseRegistrationInteractor(this._fcmRepository); + + Stream> execute(FirebaseRegistration firebaseRegistration) async* { + try { + yield Right(StoreFirebaseRegistrationLoading()); + await _fcmRepository.storeFirebaseRegistration(firebaseRegistration); + yield Right(StoreFirebaseRegistrationSuccess()); + } catch (e) { + yield Left(StoreFirebaseRegistrationFailure(e)); + } + } +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/store_subscription_interator.dart b/lib/features/push_notification/domain/usecases/store_subscription_interator.dart deleted file mode 100644 index 47901b5e8..000000000 --- a/lib/features/push_notification/domain/usecases/store_subscription_interator.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:core/presentation/state/failure.dart'; -import 'package:core/presentation/state/success.dart'; -import 'package:dartz/dartz.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/model/fcm_subscription.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/store_subscription_state.dart'; - -class StoreSubscriptionInteractor { - final FCMRepository _fcmRepository; - - StoreSubscriptionInteractor(this._fcmRepository); - - Stream> execute(FCMSubscription fcmSubscription) async* { - try { - yield Right(StoreSubscriptionLoading()); - await _fcmRepository.storeSubscription(fcmSubscription); - yield Right(StoreSubscriptionSuccess()); - } catch (e) { - yield Left(StoreSubscriptionFailure(e)); - } - } -} \ No newline at end of file diff --git a/lib/features/push_notification/domain/usecases/update_firebase_registration_token_interactor.dart b/lib/features/push_notification/domain/usecases/update_firebase_registration_token_interactor.dart new file mode 100644 index 000000000..355d9316e --- /dev/null +++ b/lib/features/push_notification/domain/usecases/update_firebase_registration_token_interactor.dart @@ -0,0 +1,24 @@ + +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/model/update_token_expired_time_request.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/update_firebase_registration_token_state.dart'; + +class UpdateFirebaseRegistrationTokenInteractor { + + final FCMRepository _fcmRepository; + + UpdateFirebaseRegistrationTokenInteractor(this._fcmRepository); + + Stream> execute(UpdateTokenExpiredTimeRequest updateTokenExpiredTimeRequest) async* { + try { + yield Right(UpdateFirebaseRegistrationTokenLoading()); + await _fcmRepository.updateFirebaseRegistrationToken(updateTokenExpiredTimeRequest); + yield Right(UpdateFirebaseRegistrationTokenSuccess()); + } catch (e) { + yield Left(UpdateFirebaseRegistrationTokenFailure(e)); + } + } +} \ No newline at end of file diff --git a/lib/features/push_notification/domain/utils/fcm_constants.dart b/lib/features/push_notification/domain/utils/fcm_constants.dart index 894bfb430..a83396db6 100644 --- a/lib/features/push_notification/domain/utils/fcm_constants.dart +++ b/lib/features/push_notification/domain/utils/fcm_constants.dart @@ -3,12 +3,13 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart'; class FcmConstants { - - static final List mailboxRuleAllowPushNotifications = [ + static final List mailboxRuleDoNotAllowPushNotifications = [ PresentationMailbox.roleDrafts, PresentationMailbox.roleSent, PresentationMailbox.roleOutbox, PresentationMailbox.roleSpam, PresentationMailbox.roleTrash ]; + + static const String firebaseRegistrationExpiredTimeProperty = 'expires'; } \ No newline at end of file diff --git a/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart b/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart index 649e9e660..d23a8d594 100644 --- a/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart +++ b/lib/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart @@ -35,21 +35,23 @@ import 'package:tmail_ui_user/features/push_notification/data/network/fcm_api.da import 'package:tmail_ui_user/features/push_notification/data/repository/fcm_repository_impl.dart'; import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/delete_email_state_to_refresh_interactor.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/destroy_subscription_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/delete_firebase_registration_cache_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/destroy_firebase_registration_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_email_changes_to_push_notification_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_email_changes_to_remove_notification_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_email_state_to_refresh_interactor.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_fcm_subscription_local_interactor.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_firebase_subscription_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_firebase_registration_by_device_id_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_mailbox_state_to_refresh_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_mailboxes_not_put_notifications_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_new_receive_email_from_notification_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_stored_email_delivery_state_interactor.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/register_new_token_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_stored_firebase_registration_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/register_new_firebase_registration_token_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_email_delivery_state_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_email_state_to_refresh_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_firebase_registration_interator.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_mailbox_state_to_refresh_interactor.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_subscription_interator.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/update_firebase_registration_token_interactor.dart'; import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart'; import 'package:tmail_ui_user/features/thread/data/datasource_impl/thread_datasource_impl.dart'; import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart'; @@ -123,13 +125,16 @@ class FcmInteractorBindings extends InteractorsBindings { Get.lazyPut(() => StoreEmailStateToRefreshInteractor(Get.find())); Get.lazyPut(() => GetEmailStateToRefreshInteractor(Get.find())); Get.lazyPut(() => DeleteEmailStateToRefreshInteractor(Get.find())); - Get.lazyPut(() => GetFirebaseSubscriptionInteractor(Get.find())); - Get.lazyPut(() => RegisterNewTokenInteractor(Get.find())); + Get.lazyPut(() => GetFirebaseRegistrationByDeviceIdInteractor(Get.find())); + Get.lazyPut(() => RegisterNewFirebaseRegistrationTokenInteractor(Get.find())); Get.lazyPut(() => StoreMailboxStateToRefreshInteractor(Get.find())); Get.lazyPut(() => GetMailboxStateToRefreshInteractor(Get.find())); - Get.lazyPut(() => StoreSubscriptionInteractor(Get.find())); - Get.lazyPut(() => GetFCMSubscriptionLocalInteractor(Get.find())); - Get.lazyPut(() => DestroySubscriptionInteractor(Get.find())); + Get.lazyPut(() => StoreFirebaseRegistrationInteractor(Get.find())); + Get.lazyPut(() => GetStoredFirebaseRegistrationInteractor(Get.find())); + Get.lazyPut(() => DestroyFirebaseRegistrationInteractor(Get.find())); + Get.lazyPut(() => UpdateFirebaseRegistrationTokenInteractor(Get.find())); + Get.lazyPut(() => DeleteFirebaseRegistrationCacheInteractor(Get.find())); + Get.lazyPut(() => DestroyFirebaseRegistrationInteractor(Get.find())); Get.lazyPut(() => GetMailboxesNotPutNotificationsInteractor(Get.find())); Get.lazyPut(() => GetNewReceiveEmailFromNotificationInteractor( Get.find(), diff --git a/lib/features/push_notification/presentation/config/fcm_configuration.dart b/lib/features/push_notification/presentation/config/fcm_configuration.dart index 77a9a7217..3693af26b 100644 --- a/lib/features/push_notification/presentation/config/fcm_configuration.dart +++ b/lib/features/push_notification/presentation/config/fcm_configuration.dart @@ -6,7 +6,7 @@ import 'package:tmail_ui_user/features/push_notification/presentation/services/f class FcmConfiguration { - static void initialize() async { + static Future initialize() async { await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); await FcmService.instance.recreateStreamController(); _initMessageListener(); diff --git a/lib/features/push_notification/presentation/controller/fcm_message_controller.dart b/lib/features/push_notification/presentation/controller/fcm_message_controller.dart index 0eddb9ecf..0213b0469 100644 --- a/lib/features/push_notification/presentation/controller/fcm_message_controller.dart +++ b/lib/features/push_notification/presentation/controller/fcm_message_controller.dart @@ -95,7 +95,7 @@ class FcmMessageController extends FcmBaseController { Future listenTokenStream() { FcmService.instance.fcmTokenStream .debounceTime(const Duration(milliseconds: FcmService.durationRefreshToken)) - .listen(FcmTokenController.instance.handleTokenAction); + .listen(FcmTokenController.instance.onFcmTokenChanged); return Future.value(); } @@ -199,23 +199,18 @@ class FcmMessageController extends FcmBaseController { FcmInteractorBindings().dependencies(); }); - await _getInteractorBindings(); + _getInteractorBindings(); await _newEmailCacheManager?.closeNewEmailHiveCacheBox(); } - Future _getInteractorBindings() { - try { - _getAuthenticatedAccountInteractor = getBinding(); - _dynamicUrlInterceptors = getBinding(); - _authorizationInterceptors = getBinding(); - _getSessionInteractor = getBinding(); - _newEmailCacheManager = getBinding(); - FcmTokenController.instance.initialize(); - } catch (e) { - logError('FcmMessageController::_getBindings(): ${e.toString()}'); - } - return Future.value(null); + void _getInteractorBindings() { + _getAuthenticatedAccountInteractor = getBinding(); + _dynamicUrlInterceptors = getBinding(); + _authorizationInterceptors = getBinding(); + _getSessionInteractor = getBinding(); + _newEmailCacheManager = getBinding(); + FcmTokenController.instance.initialize(); } void _getAuthenticatedAccount() { diff --git a/lib/features/push_notification/presentation/controller/fcm_token_controller.dart b/lib/features/push_notification/presentation/controller/fcm_token_controller.dart index 6ee1899e5..63a485ca7 100644 --- a/lib/features/push_notification/presentation/controller/fcm_token_controller.dart +++ b/lib/features/push_notification/presentation/controller/fcm_token_controller.dart @@ -4,21 +4,22 @@ import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/success.dart'; import 'package:core/utils/app_logger.dart'; import 'package:fcm/model/device_client_id.dart'; -import 'package:fcm/model/firebase_expired_time.dart'; -import 'package:fcm/model/firebase_subscription.dart'; -import 'package:fcm/model/firebase_token.dart'; -import 'package:fcm/model/type_name.dart'; +import 'package:fcm/model/firebase_registration_expired_time.dart'; +import 'package:fcm/model/firebase_registration.dart'; +import 'package:fcm/model/fcm_token.dart'; import 'package:jmap_dart_client/jmap/core/id.dart'; -import 'package:tmail_ui_user/features/manage_account/presentation/extensions/datetime_extension.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/model/fcm_subscription.dart'; +import 'package:jmap_dart_client/jmap/core/utc_date.dart'; import 'package:tmail_ui_user/features/push_notification/domain/model/register_new_token_request.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/get_fcm_subscription_local.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/get_firebase_subscription_state.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/state/register_new_token_state.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_fcm_subscription_local_interactor.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_firebase_subscription_interactor.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/register_new_token_interactor.dart'; -import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_subscription_interator.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/model/update_token_expired_time_request.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/get_firebase_registration_by_device_id_state.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/get_stored_firebase_registration_state.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/state/register_new_firebase_registration_token_state.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/delete_firebase_registration_cache_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_firebase_registration_by_device_id_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_stored_firebase_registration_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/register_new_firebase_registration_token_interactor.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_firebase_registration_interator.dart'; +import 'package:tmail_ui_user/features/push_notification/domain/usecases/update_firebase_registration_token_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/controller/fcm_base_controller.dart'; import 'package:tmail_ui_user/features/push_notification/presentation/utils/fcm_utils.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; @@ -35,146 +36,137 @@ class FcmTokenController extends FcmBaseController { static const int limitedTimeToExpire = 3; static const int extensionTimeExpire = 7; - StoreSubscriptionInteractor? _storeSubscriptionInteractor; - GetFirebaseSubscriptionInteractor? _getFirebaseSubscriptionInteractor; - RegisterNewTokenInteractor? _registerNewTokenInteractor; - GetFCMSubscriptionLocalInteractor? _getFCMSubscriptionLocalInteractor; - - FirebaseToken? _fcmToken; - DeviceClientId? _deviceClientId; + StoreFirebaseRegistrationInteractor? _storeFirebaseRegistrationInteractor; + GetFirebaseRegistrationByDeviceIdInteractor? _getFirebaseRegistrationByDeviceIdInteractor; + RegisterNewFirebaseRegistrationTokenInteractor? _registerNewFirebaseRegistrationTokenInteractor; + GetStoredFirebaseRegistrationInteractor? _getStoredFirebaseRegistrationInteractor; + UpdateFirebaseRegistrationTokenInteractor? _updateFirebaseRegistrationTokenInteractor; + DeleteFirebaseRegistrationCacheInteractor? _deleteFirebaseRegistrationCacheInteractor; void initialize() { - try { - _storeSubscriptionInteractor = getBinding(); - _getFirebaseSubscriptionInteractor = getBinding(); - _registerNewTokenInteractor = getBinding(); - _getFCMSubscriptionLocalInteractor = getBinding(); - } catch (e) { - logError('FcmTokenController::initialize(): ${e.toString()}'); - } + _storeFirebaseRegistrationInteractor = getBinding(); + _getFirebaseRegistrationByDeviceIdInteractor = getBinding(); + _registerNewFirebaseRegistrationTokenInteractor = getBinding(); + _getStoredFirebaseRegistrationInteractor = getBinding(); + _updateFirebaseRegistrationTokenInteractor = getBinding(); + _deleteFirebaseRegistrationCacheInteractor = getBinding(); } - void handleTokenAction(String? token) { - log('FcmTokenController::handleTokenAction():token: $token'); - if (token != null) { - _fcmToken = FirebaseToken(token); - final deviceId = FcmUtils.instance.hashTokenToDeviceId(token); - _deviceClientId = DeviceClientId(deviceId); - log('FcmTokenController::handleTokenAction(): fcmToken: $_fcmToken'); - log('FcmTokenController::handleTokenAction(): deviceId: $deviceId'); - _getFcmTokenFromBackend(deviceId); + void onFcmTokenChanged(String? newToken) { + log('FcmTokenController::onFcmTokenChanged():newToken: $newToken'); + if (newToken != null) { + _getFirebaseRegistrationFromServer( + newFcmToken: FcmToken(newToken), + deviceClientId: DeviceClientId(FcmUtils.instance.hashTokenToDeviceId(newToken)) + ); } else { - _getFCMSubscriptionLocalAction(); + _getStoredFirebaseRegistrationFromCache(); } } - void _getFcmTokenFromBackend(String deviceId) { - if (_getFirebaseSubscriptionInteractor != null) { - consumeState(_getFirebaseSubscriptionInteractor!.execute(deviceId)); + void _getFirebaseRegistrationFromServer({ + required DeviceClientId deviceClientId, + FcmToken? newFcmToken + }) { + if (_getFirebaseRegistrationByDeviceIdInteractor != null) { + consumeState( + _getFirebaseRegistrationByDeviceIdInteractor!.execute( + deviceClientId: deviceClientId, + newFcmToken: newFcmToken + ) + ); + } else if (newFcmToken != null) { + _registerNewFirebaseRegistrationToken(newFcmToken); } } - void _storeSubscriptionAction(FCMSubscription fcmSubscription){ - if (_storeSubscriptionInteractor != null) { - consumeState(_storeSubscriptionInteractor!.execute(fcmSubscription)); + void _getStoredFirebaseRegistrationFromCache() { + if (_getStoredFirebaseRegistrationInteractor != null) { + consumeState(_getStoredFirebaseRegistrationInteractor!.execute()); } } - bool _isTokenExpired(FirebaseExpiredTime? expireTime) { - log('FcmTokenController::_isTokenExpired():expireTime: $expireTime'); - if (expireTime != null) { - final expireTimeLocal = expireTime.value.value.toLocal(); + void _storeFirebaseRegistrationToCache(FirebaseRegistration firebaseRegistration){ + if (_storeFirebaseRegistrationInteractor != null) { + consumeState(_storeFirebaseRegistrationInteractor!.execute(firebaseRegistration)); + } + } + + bool _validateFirebaseRegistrationTokenExpired(FirebaseRegistration firebaseRegistration) { + log('FcmTokenController::_validateFirebaseRegistrationTokenExpired():firebaseRegistration: $firebaseRegistration'); + if (firebaseRegistration.expires != null) { + final expireTimeLocal = firebaseRegistration.expires!.value.value.toLocal(); final currentTime = DateTime.now(); - - log('FcmTokenController::_isTokenExpired():expireTimeLocal: $expireTimeLocal'); - log('FcmTokenController::_isTokenExpired():currentTime: $currentTime'); - - return currentTime.isBefore(expireTimeLocal) && - expireTimeLocal.daysBetween(currentTime) <= limitedTimeToExpire; + log('FcmTokenController::_validateFirebaseRegistrationTokenExpired():expireTimeLocal: $expireTimeLocal | currentTime: $currentTime'); + final offsetTime = expireTimeLocal.minutesBetween(currentTime); + log('FcmTokenController::_validateFirebaseRegistrationTokenExpired():offsetTime: $offsetTime'); + return currentTime.isBefore(expireTimeLocal) && offsetTime <= limitedTimeToExpire; } else { return true; } } - void _handleWhenTokenExpired() { - if (_fcmToken == null || _deviceClientId == null) { - log('FcmTokenController::_handleSuccessViewState():_fcmToken or _deviceClientId is null'); - return; + void _updateNewExpiredTimeForFirebaseRegistration(FirebaseRegistration firebaseRegistration) { + log('FcmTokenController::_updateNewExpiredTimeForFirebaseRegistration():firebaseRegistration: $firebaseRegistration'); + if (_updateFirebaseRegistrationTokenInteractor != null && firebaseRegistration.id != null) { + final newExpiredTime = DateTime.now().add(const Duration(days: extensionTimeExpire)); + consumeState( + _updateFirebaseRegistrationTokenInteractor!.execute( + UpdateTokenExpiredTimeRequest( + firebaseRegistration.id!, + FirebaseRegistrationExpiredTime(UTCDate(newExpiredTime)), + ) + ) + ); } - - final generateCreationId = Id(const Uuid().v4()); - final newExpireTime = DateTime.now().add(const Duration(days: extensionTimeExpire)); - - log('FcmTokenController::_handleSuccessViewState():newExpireTime: $newExpireTime'); - final firebaseSubscription = FirebaseSubscription( - token: _fcmToken!, - expires: FirebaseExpiredTime(newExpireTime.toUTCDate()!), - deviceClientId: _deviceClientId!, - types: [TypeName.emailType, TypeName.mailboxType, TypeName.emailDelivery] - ); - - log('FcmTokenController::_handleSuccessViewState():firebaseSubscription: $firebaseSubscription'); - _invokeRegisterNewTokenAction(RegisterNewTokenRequest( - generateCreationId, - firebaseSubscription - )); } - void _handleRegisterNewToken(FirebaseToken fcmToken, DeviceClientId deviceClientId) { + void _registerNewFirebaseRegistrationToken(FcmToken fcmToken) { final generateCreationId = Id(const Uuid().v4()); - final firebaseSubscription = FirebaseSubscription( + final firebaseRegistration = FirebaseRegistration( token: fcmToken, - deviceClientId: deviceClientId, - types: [TypeName.emailType, TypeName.mailboxType, TypeName.emailDelivery] + deviceClientId: DeviceClientId(FcmUtils.instance.hashTokenToDeviceId(fcmToken.value)), + types: FcmUtils.defaultFirebaseRegistrationTypes ); - log('FcmTokenController::_handleRegisterNewToken():firebaseSubscription: $firebaseSubscription'); - _invokeRegisterNewTokenAction(RegisterNewTokenRequest( - generateCreationId, - firebaseSubscription - )); - } - - void _invokeRegisterNewTokenAction(RegisterNewTokenRequest newTokenRequest) { - if (_registerNewTokenInteractor != null) { - consumeState(_registerNewTokenInteractor!.execute(newTokenRequest)); + log('FcmTokenController::_registerNewFirebaseRegistrationToken():generateCreationId: $generateCreationId | firebaseRegistration: $firebaseRegistration'); + if (_registerNewFirebaseRegistrationTokenInteractor != null) { + consumeState( + _registerNewFirebaseRegistrationTokenInteractor!.execute( + RegisterNewTokenRequest( + generateCreationId, + firebaseRegistration + ) + ) + ); } } - - void _getFCMSubscriptionLocalAction() { - if (_getFCMSubscriptionLocalInteractor != null) { - consumeState(_getFCMSubscriptionLocalInteractor!.execute()); + + void _deleteFirebaseRegistrationInCache() { + if (_deleteFirebaseRegistrationCacheInteractor != null) { + consumeState(_deleteFirebaseRegistrationCacheInteractor!.execute()); } } @override void handleFailureViewState(Failure failure) { log('FcmTokenController::_handleFailureViewState(): $failure'); - if (failure is GetFirebaseSubscriptionFailure) { - if (_fcmToken != null && _deviceClientId != null) { - _handleRegisterNewToken(_fcmToken!, _deviceClientId!); - } + if (failure is GetFirebaseRegistrationByDeviceIdFailure && failure.newFcmToken != null) { + _registerNewFirebaseRegistrationToken(failure.newFcmToken!); + } else if (failure is RegisterNewFirebaseRegistrationTokenFailure) { + _deleteFirebaseRegistrationInCache(); } } @override void handleSuccessViewState(Success success) { log('FcmTokenController::_handleSuccessViewState(): $success'); - if (success is GetFirebaseSubscriptionSuccess) { - _deviceClientId = success.firebaseSubscription.deviceClientId; - final expireTime = success.firebaseSubscription.expires; - log('FcmTokenController::_handleSuccessViewState():_fcmToken: $_fcmToken'); - if (_isTokenExpired(expireTime)) { - log('FcmTokenController::_handleSuccessViewState(): _isTokenExpired true'); - _handleWhenTokenExpired(); - } - } else if (success is RegisterNewTokenSuccess) { - final deviceId = success.firebaseSubscription.deviceClientId?.value; - final subscriptionId = success.firebaseSubscription.id?.id.value; - if (deviceId != null && subscriptionId != null) { - _storeSubscriptionAction(FCMSubscription(deviceId, subscriptionId)); - } - } else if (success is GetFCMSubscriptionLocalSuccess) { - _getFcmTokenFromBackend(success.fcmSubscription.deviceId); + if (success is GetFirebaseRegistrationByDeviceIdSuccess && + _validateFirebaseRegistrationTokenExpired(success.firebaseRegistration)) { + _updateNewExpiredTimeForFirebaseRegistration(success.firebaseRegistration); + } else if (success is GetStoredFirebaseRegistrationSuccess) { + _getFirebaseRegistrationFromServer(deviceClientId: success.firebaseRegistration.deviceClientId!); + } else if (success is RegisterNewFirebaseRegistrationTokenSuccess) { + _storeFirebaseRegistrationToCache(success.firebaseRegistration); } } } \ No newline at end of file diff --git a/lib/features/push_notification/presentation/utils/fcm_utils.dart b/lib/features/push_notification/presentation/utils/fcm_utils.dart index b72057433..d4114e223 100644 --- a/lib/features/push_notification/presentation/utils/fcm_utils.dart +++ b/lib/features/push_notification/presentation/utils/fcm_utils.dart @@ -18,6 +18,11 @@ class FcmUtils { static FcmUtils get instance => _instance; static const String hashCodeKey = 'TeamMail'; + static final List defaultFirebaseRegistrationTypes = [ + TypeName.emailType, + TypeName.mailboxType, + TypeName.emailDelivery + ]; StateChange? convertFirebaseDataMessageToStateChange(Map dataMessage) { log('FcmUtils::convertFirebaseDataMessageToStateChange():dataMessage: $dataMessage'); diff --git a/lib/main/bindings/local/local_bindings.dart b/lib/main/bindings/local/local_bindings.dart index 8720a78ac..38fd8eeb0 100644 --- a/lib/main/bindings/local/local_bindings.dart +++ b/lib/main/bindings/local/local_bindings.dart @@ -18,7 +18,7 @@ import 'package:tmail_ui_user/features/caching/clients/recent_search_cache_clien import 'package:tmail_ui_user/features/caching/clients/sending_email_hive_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/session_hive_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/state_cache_client.dart'; -import 'package:tmail_ui_user/features/caching/clients/subscription_cache_client.dart'; +import 'package:tmail_ui_user/features/caching/clients/firebase_registration_cache_client.dart'; import 'package:tmail_ui_user/features/caching/clients/token_oidc_cache_client.dart'; import 'package:tmail_ui_user/features/cleanup/data/local/recent_login_url_cache_manager.dart'; import 'package:tmail_ui_user/features/cleanup/data/local/recent_login_username_cache_manager.dart'; @@ -71,9 +71,9 @@ class LocalBindings extends Bindings { Get.put(RecentLoginUrlCacheManager((Get.find()))); Get.put(RecentLoginUsernameCacheClient()); Get.put(RecentLoginUsernameCacheManager(Get.find())); - Get.put(FCMSubscriptionCacheClient()); + Get.put(FirebaseRegistrationCacheClient()); Get.put(FcmCacheClient()); - Get.put(FCMCacheManager(Get.find(),Get.find())); + Get.put(FCMCacheManager(Get.find(),Get.find())); Get.put(HiveCacheVersionClient(Get.find(), Get.find())); Get.put(NewEmailHiveCacheClient()); Get.put(NewEmailCacheManager(Get.find(), Get.find())); @@ -90,7 +90,7 @@ class LocalBindings extends Bindings { Get.find(), Get.find(), Get.find(), - Get.find(), + Get.find(), Get.find(), Get.find(), Get.find(),