TF-439 Handle get stored device id

This commit is contained in:
dab246
2022-11-29 16:45:49 +07:00
committed by Dat H. Pham
parent ce1a52caac
commit 81278d13ba
12 changed files with 121 additions and 11 deletions
@@ -1285,7 +1285,7 @@ class MailboxDashBoardController extends ReloadableController {
void _handleRefreshActionWhenBackToApp(RefreshActionViewEvent viewEvent) { void _handleRefreshActionWhenBackToApp(RefreshActionViewEvent viewEvent) {
log('MailboxDashBoardController::_handleRefreshActionWhenBackToApp():'); log('MailboxDashBoardController::_handleRefreshActionWhenBackToApp():');
try { try {
_getEmailStateToRefreshInteractor = Get.find<GetEmailStateToRefreshInteractor>(); _getEmailStateToRefreshInteractor = getBinding<GetEmailStateToRefreshInteractor>();
} catch (e) { } catch (e) {
logError('MailboxDashBoardController::_handleRefreshActionWhenBackToApp(): $e'); logError('MailboxDashBoardController::_handleRefreshActionWhenBackToApp(): $e');
} }
@@ -1297,7 +1297,7 @@ class MailboxDashBoardController extends ReloadableController {
void _deleteEmailStateToRefreshAction() { void _deleteEmailStateToRefreshAction() {
log('MailboxDashBoardController::_deleteEmailStateToRefreshAction():'); log('MailboxDashBoardController::_deleteEmailStateToRefreshAction():');
try { try {
_deleteEmailStateToRefreshInteractor = Get.find<DeleteEmailStateToRefreshInteractor>(); _deleteEmailStateToRefreshInteractor = getBinding<DeleteEmailStateToRefreshInteractor>();
} catch (e) { } catch (e) {
logError('MailboxDashBoardController::_deleteEmailStateToRefreshAction(): $e'); logError('MailboxDashBoardController::_deleteEmailStateToRefreshAction(): $e');
} }
@@ -23,4 +23,6 @@ abstract class FCMDatasource {
Future<FirebaseSubscription> getFirebaseSubscriptionByDeviceId(String deviceId); Future<FirebaseSubscription> getFirebaseSubscriptionByDeviceId(String deviceId);
Future<FirebaseSubscription> registerNewToken(RegisterNewTokenRequest newTokenRequest); Future<FirebaseSubscription> registerNewToken(RegisterNewTokenRequest newTokenRequest);
Future<String> getDeviceId();
} }
@@ -66,4 +66,9 @@ class FcmDatasourceImpl extends FCMDatasource {
_exceptionThrower.throwException(error); _exceptionThrower.throwException(error);
}); });
} }
@override
Future<String> getDeviceId() {
throw UnimplementedError();
}
} }
@@ -83,7 +83,16 @@ class HiveFCMDatasourceImpl extends FCMDatasource {
} }
@override @override
Future<FirebaseSubscription> registerNewToken(RegisterNewTokenRequest registerNewTokenRequest) { Future<FirebaseSubscription> registerNewToken(RegisterNewTokenRequest newTokenRequest) {
throw UnimplementedError(); throw UnimplementedError();
} }
@override
Future<String> getDeviceId() {
return Future.sync(() async {
return await _firebaseCacheManager.getDeviceId();
}).catchError((error) {
_exceptionThrower.throwException(error);
});
}
} }
@@ -75,4 +75,14 @@ class FCMCacheManager {
Future<bool> storeDeviceId(String deviceId) { Future<bool> storeDeviceId(String deviceId) {
return _sharedPreferences.setString(fcmDeviceIdKey, deviceId); return _sharedPreferences.setString(fcmDeviceIdKey, deviceId);
} }
Future<String> getDeviceId() async {
await _sharedPreferences.reload();
final deviceId = _sharedPreferences.getString(fcmDeviceIdKey);
if (deviceId != null) {
return deviceId;
} else {
throw NotFoundDeviceIdException();
}
}
} }
@@ -104,4 +104,9 @@ class FCMRepositoryImpl extends FCMRepository {
Future<FirebaseSubscription> registerNewToken(RegisterNewTokenRequest newTokenRequest) { Future<FirebaseSubscription> registerNewToken(RegisterNewTokenRequest newTokenRequest) {
return _fcmDatasource[DataSourceType.network]!.registerNewToken(newTokenRequest); return _fcmDatasource[DataSourceType.network]!.registerNewToken(newTokenRequest);
} }
@override
Future<String> getDeviceId() {
return _fcmDatasource[DataSourceType.local]!.getDeviceId();
}
} }
@@ -7,3 +7,5 @@ class NotFoundStateToRefreshException implements Exception {}
class NotFoundEmailDeliveryStateException implements Exception {} class NotFoundEmailDeliveryStateException implements Exception {}
class NotFoundFirebaseSubscriptionException implements Exception {} class NotFoundFirebaseSubscriptionException implements Exception {}
class NotFoundDeviceIdException implements Exception {}
@@ -34,4 +34,6 @@ abstract class FCMRepository {
Future<FirebaseSubscription> getFirebaseSubscriptionByDeviceId(String deviceId); Future<FirebaseSubscription> getFirebaseSubscriptionByDeviceId(String deviceId);
Future<FirebaseSubscription> registerNewToken(RegisterNewTokenRequest newTokenRequest); Future<FirebaseSubscription> registerNewToken(RegisterNewTokenRequest newTokenRequest);
Future<String> getDeviceId();
} }
@@ -0,0 +1,24 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
class GetDeviceIdLoading extends UIState {}
class GetDeviceIdSuccess extends UIState {
final String deviceId;
GetDeviceIdSuccess(this.deviceId);
@override
List<Object> get props => [deviceId];
}
class GetDeviceIdFailure extends FeatureFailure {
final dynamic exception;
GetDeviceIdFailure(this.exception);
@override
List<Object> get props => [exception];
}
@@ -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_device_id_state.dart';
class GetDeviceIdInteractor {
final FCMRepository _fcmRepository;
GetDeviceIdInteractor(this._fcmRepository);
Stream<Either<Failure, Success>> execute() async* {
try {
yield Right<Failure, Success>(GetDeviceIdLoading());
final deviceId = await _fcmRepository.getDeviceId();
yield Right<Failure, Success>(GetDeviceIdSuccess(deviceId));
} catch (e) {
yield Left<Failure, Success>(GetDeviceIdFailure(e));
}
}
}
@@ -10,6 +10,7 @@ import 'package:tmail_ui_user/features/push_notification/data/repository/fcm_rep
import 'package:tmail_ui_user/features/push_notification/domain/repository/fcm_repository.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/delete_email_state_to_refresh_interactor.dart';
import 'package:tmail_ui_user/features/push_notification/domain/usecases/delete_fcm_token_cache_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/delete_fcm_token_cache_interactor.dart';
import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_device_id_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_push_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_email_state_to_refresh_interactor.dart';
import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_fcm_token_cache_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_fcm_token_cache_interactor.dart';
@@ -66,6 +67,7 @@ class FcmInteractorBindings extends InteractorsBindings {
Get.lazyPut(() => StoreDeviceIdInteractor(Get.find<FCMRepositoryImpl>())); Get.lazyPut(() => StoreDeviceIdInteractor(Get.find<FCMRepositoryImpl>()));
Get.lazyPut(() => GetFirebaseSubscriptionInteractor(Get.find<FCMRepositoryImpl>())); Get.lazyPut(() => GetFirebaseSubscriptionInteractor(Get.find<FCMRepositoryImpl>()));
Get.lazyPut(() => RegisterNewTokenInteractor(Get.find<FCMRepositoryImpl>())); Get.lazyPut(() => RegisterNewTokenInteractor(Get.find<FCMRepositoryImpl>()));
Get.lazyPut(() => GetDeviceIdInteractor(Get.find<FCMRepositoryImpl>()));
} }
@override @override
@@ -12,7 +12,10 @@ import 'package:fcm/model/type_name.dart';
import 'package:jmap_dart_client/jmap/core/id.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/manage_account/presentation/extensions/datetime_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/register_new_token_request.dart';
import 'package:tmail_ui_user/features/push_notification/domain/state/get_device_id_state.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/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_device_id_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_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/register_new_token_interactor.dart';
import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_device_id_interactor.dart'; import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_device_id_interactor.dart';
@@ -28,9 +31,13 @@ class FcmTokenHandler {
static FcmTokenHandler get instance => _instance; static FcmTokenHandler get instance => _instance;
static const int limitedTimeToExpire = 3;
static const int extensionTimeExpire = 7;
StoreDeviceIdInteractor? _storeDeviceIdInteractor; StoreDeviceIdInteractor? _storeDeviceIdInteractor;
GetFirebaseSubscriptionInteractor? _getFirebaseSubscriptionInteractor; GetFirebaseSubscriptionInteractor? _getFirebaseSubscriptionInteractor;
RegisterNewTokenInteractor? _registerNewTokenInteractor; RegisterNewTokenInteractor? _registerNewTokenInteractor;
GetDeviceIdInteractor? _getDeviceIdInteractor;
FirebaseToken? _fcmToken; FirebaseToken? _fcmToken;
DeviceClientId? _deviceClientId; DeviceClientId? _deviceClientId;
@@ -40,6 +47,7 @@ class FcmTokenHandler {
_storeDeviceIdInteractor = getBinding<StoreDeviceIdInteractor>(); _storeDeviceIdInteractor = getBinding<StoreDeviceIdInteractor>();
_getFirebaseSubscriptionInteractor = getBinding<GetFirebaseSubscriptionInteractor>(); _getFirebaseSubscriptionInteractor = getBinding<GetFirebaseSubscriptionInteractor>();
_registerNewTokenInteractor = getBinding<RegisterNewTokenInteractor>(); _registerNewTokenInteractor = getBinding<RegisterNewTokenInteractor>();
_getDeviceIdInteractor = getBinding<GetDeviceIdInteractor>();
} catch (e) { } catch (e) {
logError('FcmTokenHandler::initialize(): ${e.toString()}'); logError('FcmTokenHandler::initialize(): ${e.toString()}');
} }
@@ -54,6 +62,8 @@ class FcmTokenHandler {
log('FcmTokenHandler::handle(): fcmToken: $_fcmToken'); log('FcmTokenHandler::handle(): fcmToken: $_fcmToken');
log('FcmTokenHandler::handle(): deviceId: $deviceId'); log('FcmTokenHandler::handle(): deviceId: $deviceId');
_getFcmTokenFromBackend(deviceId); _getFcmTokenFromBackend(deviceId);
} else {
_getDeviceIdAction();
} }
} }
@@ -69,6 +79,12 @@ class FcmTokenHandler {
} }
} }
void _getDeviceIdAction() {
if (_getDeviceIdInteractor != null) {
_consumeState(_getDeviceIdInteractor!.execute());
}
}
void _consumeState(Stream<Either<Failure, Success>> newStateStream) { void _consumeState(Stream<Either<Failure, Success>> newStateStream) {
newStateStream.listen( newStateStream.listen(
_handleStateStream, _handleStateStream,
@@ -95,13 +111,20 @@ class FcmTokenHandler {
void _handleSuccessViewState(Success success) { void _handleSuccessViewState(Success success) {
log('FcmTokenHandler::_handleSuccessViewState(): $success'); log('FcmTokenHandler::_handleSuccessViewState(): $success');
if (success is GetFirebaseSubscriptionSuccess) { if (success is GetFirebaseSubscriptionSuccess) {
_fcmToken = success.firebaseSubscription.token;
_deviceClientId = success.firebaseSubscription.deviceClientId; _deviceClientId = success.firebaseSubscription.deviceClientId;
final expireTime = success.firebaseSubscription.expires; final expireTime = success.firebaseSubscription.expires;
log('FcmTokenHandler::_handleSuccessViewState():_fcmToken: $_fcmToken'); log('FcmTokenHandler::_handleSuccessViewState():_fcmToken: $_fcmToken');
if (_isTokenExpired(expireTime)) { if (_isTokenExpired(expireTime)) {
_handleWhenTokenExpired(_fcmToken!, _deviceClientId!); log('FcmTokenHandler::_handleSuccessViewState(): _isTokenExpired true');
_handleWhenTokenExpired();
} }
} else if (success is RegisterNewTokenSuccess) {
final deviceId = success.firebaseSubscription.deviceClientId?.value;
if (deviceId != null) {
_storeDeviceIdAction(deviceId);
}
} else if (success is GetDeviceIdSuccess) {
_getFcmTokenFromBackend(success.deviceId);
} }
} }
@@ -115,21 +138,26 @@ class FcmTokenHandler {
log('FcmTokenHandler::_isTokenExpired():currentTime: $currentTime'); log('FcmTokenHandler::_isTokenExpired():currentTime: $currentTime');
return currentTime.isBefore(expireTimeLocal) && return currentTime.isBefore(expireTimeLocal) &&
expireTimeLocal.daysBetween(currentTime) == 3; expireTimeLocal.daysBetween(currentTime) <= limitedTimeToExpire;
} else { } else {
return true; return true;
} }
} }
void _handleWhenTokenExpired(FirebaseToken fcmToken, DeviceClientId deviceClientId) { void _handleWhenTokenExpired() {
if (_fcmToken == null || _deviceClientId == null) {
log('FcmTokenHandler::_handleSuccessViewState():_fcmToken or _deviceClientId is null');
return;
}
final generateCreationId = Id(const Uuid().v4()); final generateCreationId = Id(const Uuid().v4());
final newExpireTime = DateTime.now().add(const Duration(days: 7)); final newExpireTime = DateTime.now().add(const Duration(days: extensionTimeExpire));
log('FcmTokenHandler::_handleSuccessViewState():newExpireTime: $newExpireTime'); log('FcmTokenHandler::_handleSuccessViewState():newExpireTime: $newExpireTime');
final firebaseSubscription = FirebaseSubscription( final firebaseSubscription = FirebaseSubscription(
token: fcmToken, token: _fcmToken!,
expires: FirebaseExpiredTime(newExpireTime.toUTCDate()!), expires: FirebaseExpiredTime(newExpireTime.toUTCDate()!),
deviceClientId: deviceClientId, deviceClientId: _deviceClientId!,
types: [TypeName.emailType, TypeName.mailboxType, TypeName.emailDelivery] types: [TypeName.emailType, TypeName.mailboxType, TypeName.emailDelivery]
); );