TF-439 Implement handle store device id
This commit is contained in:
@@ -65,4 +65,13 @@ class HiveFCMDatasourceImpl extends FCMDatasource {
|
|||||||
_exceptionThrower.throwException(error);
|
_exceptionThrower.throwException(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> storeDeviceId(String deviceId) {
|
||||||
|
return Future.sync(() async {
|
||||||
|
return await _firebaseCacheManager.storeDeviceId(deviceId);
|
||||||
|
}).catchError((error) {
|
||||||
|
_exceptionThrower.throwException(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,8 @@ class FCMCacheManager {
|
|||||||
final FcmTokenCacheClient _fcmTokenCacheClient;
|
final FcmTokenCacheClient _fcmTokenCacheClient;
|
||||||
final SharedPreferences _sharedPreferences;
|
final SharedPreferences _sharedPreferences;
|
||||||
|
|
||||||
|
static const String fcmDeviceIdKey = 'FCM_DEVICE_ID';
|
||||||
|
|
||||||
FCMCacheManager(this._fcmTokenCacheClient, this._sharedPreferences);
|
FCMCacheManager(this._fcmTokenCacheClient, this._sharedPreferences);
|
||||||
|
|
||||||
Future<FCMTokenDto> getFCMToken(String accountId) async {
|
Future<FCMTokenDto> getFCMToken(String accountId) async {
|
||||||
@@ -69,4 +71,8 @@ class FCMCacheManager {
|
|||||||
_sharedPreferences.remove(TypeName.emailDelivery.value)
|
_sharedPreferences.remove(TypeName.emailDelivery.value)
|
||||||
]).then((listResult) => listResult.every((result) => result));
|
]).then((listResult) => listResult.every((result) => result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> storeDeviceId(String deviceId) {
|
||||||
|
return _sharedPreferences.setString(fcmDeviceIdKey, deviceId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -88,4 +88,9 @@ class FCMRepositoryImpl extends FCMRepository {
|
|||||||
Future<bool> deleteStateToRefresh(TypeName typeName) {
|
Future<bool> deleteStateToRefresh(TypeName typeName) {
|
||||||
return _fcmDatasource.deleteStateToRefresh(typeName);
|
return _fcmDatasource.deleteStateToRefresh(typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> storeDeviceId(String deviceId) {
|
||||||
|
return _fcmDatasource.storeDeviceId(deviceId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
import 'package:core/presentation/state/failure.dart';
|
||||||
|
import 'package:core/presentation/state/success.dart';
|
||||||
|
|
||||||
|
class StoreDeviceIdLoading extends UIState {}
|
||||||
|
|
||||||
|
class StoreDeviceIdSuccess extends UIState {
|
||||||
|
|
||||||
|
StoreDeviceIdSuccess();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class StoreDeviceIdFailure extends FeatureFailure {
|
||||||
|
final dynamic exception;
|
||||||
|
|
||||||
|
StoreDeviceIdFailure(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/store_device_id_state.dart';
|
||||||
|
|
||||||
|
class StoreDeviceIdInteractor {
|
||||||
|
final FCMRepository _fcmRepository;
|
||||||
|
|
||||||
|
StoreDeviceIdInteractor(this._fcmRepository);
|
||||||
|
|
||||||
|
Stream<Either<Failure, Success>> execute(String deviceId) async* {
|
||||||
|
try {
|
||||||
|
yield Right<Failure, Success>(StoreDeviceIdLoading());
|
||||||
|
await _fcmRepository.storeDeviceId(deviceId);
|
||||||
|
yield Right<Failure, Success>(StoreDeviceIdSuccess());
|
||||||
|
} catch (e) {
|
||||||
|
yield Left<Failure, Success>(StoreDeviceIdFailure(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ import 'package:tmail_ui_user/features/push_notification/domain/usecases/get_ema
|
|||||||
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';
|
||||||
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/get_stored_email_delivery_state_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/push_notification/domain/usecases/save_fcm_token_cache_interactor.dart';
|
import 'package:tmail_ui_user/features/push_notification/domain/usecases/save_fcm_token_cache_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_email_delivery_state_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_email_state_to_refresh_interactor.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
||||||
@@ -53,6 +54,7 @@ class FcmInteractorBindings extends InteractorsBindings {
|
|||||||
Get.lazyPut(() => StoreEmailStateToRefreshInteractor(Get.find<FCMRepositoryImpl>()));
|
Get.lazyPut(() => StoreEmailStateToRefreshInteractor(Get.find<FCMRepositoryImpl>()));
|
||||||
Get.lazyPut(() => GetEmailStateToRefreshInteractor(Get.find<FCMRepositoryImpl>()));
|
Get.lazyPut(() => GetEmailStateToRefreshInteractor(Get.find<FCMRepositoryImpl>()));
|
||||||
Get.lazyPut(() => DeleteEmailStateToRefreshInteractor(Get.find<FCMRepositoryImpl>()));
|
Get.lazyPut(() => DeleteEmailStateToRefreshInteractor(Get.find<FCMRepositoryImpl>()));
|
||||||
|
Get.lazyPut(() => StoreDeviceIdInteractor(Get.find<FCMRepositoryImpl>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import 'package:tmail_ui_user/features/login/domain/usecases/get_authenticated_a
|
|||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart';
|
||||||
import 'package:tmail_ui_user/features/push_notification/presentation/action/fcm_action.dart';
|
import 'package:tmail_ui_user/features/push_notification/presentation/action/fcm_action.dart';
|
||||||
import 'package:tmail_ui_user/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart';
|
import 'package:tmail_ui_user/features/push_notification/presentation/bindings/fcm_interactor_bindings.dart';
|
||||||
|
import 'package:tmail_ui_user/features/push_notification/presentation/controller/fcm_token_handler.dart';
|
||||||
import 'package:tmail_ui_user/features/push_notification/presentation/extensions/state_change_extension.dart';
|
import 'package:tmail_ui_user/features/push_notification/presentation/extensions/state_change_extension.dart';
|
||||||
import 'package:tmail_ui_user/features/push_notification/presentation/listener/email_change_listener.dart';
|
import 'package:tmail_ui_user/features/push_notification/presentation/listener/email_change_listener.dart';
|
||||||
import 'package:tmail_ui_user/features/push_notification/presentation/services/fcm_service.dart';
|
import 'package:tmail_ui_user/features/push_notification/presentation/services/fcm_service.dart';
|
||||||
@@ -54,6 +55,7 @@ class FcmController extends BaseController {
|
|||||||
|
|
||||||
void initialize({AccountId? accountId}) {
|
void initialize({AccountId? accountId}) {
|
||||||
_currentAccountId = accountId;
|
_currentAccountId = accountId;
|
||||||
|
FcmTokenHandler.instance.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenFcmMessageStream() {
|
void _listenFcmMessageStream() {
|
||||||
@@ -65,6 +67,8 @@ class FcmController extends BaseController {
|
|||||||
FcmService.instance.backgroundMessageStream
|
FcmService.instance.backgroundMessageStream
|
||||||
.throttleTime(const Duration(milliseconds: FcmService.durationMessageComing))
|
.throttleTime(const Duration(milliseconds: FcmService.durationMessageComing))
|
||||||
.listen(_handleBackgroundMessageAction);
|
.listen(_handleBackgroundMessageAction);
|
||||||
|
|
||||||
|
FcmService.instance.fcmTokenStream.listen(FcmTokenHandler.instance.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleForegroundMessageAction(RemoteMessage newRemoteMessage) {
|
void _handleForegroundMessageAction(RemoteMessage newRemoteMessage) {
|
||||||
@@ -151,6 +155,7 @@ class FcmController extends BaseController {
|
|||||||
_dynamicUrlInterceptors = Get.find<DynamicUrlInterceptors>();
|
_dynamicUrlInterceptors = Get.find<DynamicUrlInterceptors>();
|
||||||
_authorizationInterceptors = Get.find<AuthorizationInterceptors>();
|
_authorizationInterceptors = Get.find<AuthorizationInterceptors>();
|
||||||
_getSessionInteractor = Get.find<GetSessionInteractor>();
|
_getSessionInteractor = Get.find<GetSessionInteractor>();
|
||||||
|
FcmTokenHandler.instance.initialize();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError('FcmController::_getBindings(): ${e.toString()}');
|
logError('FcmController::_getBindings(): ${e.toString()}');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
import 'package:core/presentation/state/failure.dart';
|
||||||
|
import 'package:core/presentation/state/success.dart';
|
||||||
|
import 'package:core/utils/app_logger.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:fcm/model/firebase_token.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:tmail_ui_user/features/push_notification/domain/usecases/store_device_id_interactor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/push_notification/presentation/utils/fcm_utils.dart';
|
||||||
|
|
||||||
|
class FcmTokenHandler {
|
||||||
|
|
||||||
|
FcmTokenHandler._internal();
|
||||||
|
|
||||||
|
static final FcmTokenHandler _instance = FcmTokenHandler._internal();
|
||||||
|
|
||||||
|
static FcmTokenHandler get instance => _instance;
|
||||||
|
|
||||||
|
StoreDeviceIdInteractor? _storeDeviceIdInteractor;
|
||||||
|
|
||||||
|
void initialize() {
|
||||||
|
try {
|
||||||
|
_storeDeviceIdInteractor = Get.find<StoreDeviceIdInteractor>();
|
||||||
|
} catch (e) {
|
||||||
|
logError('FcmTokenHandler::initialize(): ${e.toString()}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle(String token) {
|
||||||
|
log('FcmTokenHandler::handle():token: $token');
|
||||||
|
final fcmToken = FirebaseToken(token);
|
||||||
|
final deviceId = FcmUtils.instance.hashTokenToDeviceId(token);
|
||||||
|
log('FcmTokenHandler::handle(): fcmToken: $fcmToken');
|
||||||
|
log('FcmTokenHandler::handle(): deviceId: $deviceId');
|
||||||
|
_storeDeviceIdAction(deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _storeDeviceIdAction(String deviceId) {
|
||||||
|
if (_storeDeviceIdInteractor != null) {
|
||||||
|
_consumeState(_storeDeviceIdInteractor!.execute(deviceId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _consumeState(Stream<Either<Failure, Success>> newStateStream) {
|
||||||
|
newStateStream.listen(
|
||||||
|
_handleStateStream,
|
||||||
|
onError: (error, stackTrace) {
|
||||||
|
logError('FcmTokenHandler::consumeState():onError:error: $error');
|
||||||
|
logError('FcmTokenHandler::consumeState():onError:stackTrace: $stackTrace');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleStateStream(Either<Failure, Success> newState) {
|
||||||
|
newState.fold(_handleFailureViewState, _handleSuccessViewState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleFailureViewState(Failure failure) {
|
||||||
|
log('FcmTokenHandler::_handleFailureViewState(): $failure');
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleSuccessViewState(Success success) {
|
||||||
|
log('FcmTokenHandler::_handleSuccessViewState(): $success');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:core/utils/app_logger.dart';
|
import 'package:core/utils/app_logger.dart';
|
||||||
import 'package:fcm/model/firebase_token.dart';
|
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:tmail_ui_user/features/push_notification/presentation/controller/fcm_controller.dart';
|
import 'package:tmail_ui_user/features/push_notification/presentation/controller/fcm_controller.dart';
|
||||||
|
|
||||||
@@ -19,8 +18,6 @@ class FcmService {
|
|||||||
final StreamController<String> fcmTokenStreamController = StreamController<String>.broadcast();
|
final StreamController<String> fcmTokenStreamController = StreamController<String>.broadcast();
|
||||||
Stream<String> get fcmTokenStream => fcmTokenStreamController.stream;
|
Stream<String> get fcmTokenStream => fcmTokenStreamController.stream;
|
||||||
|
|
||||||
FirebaseToken? currentToken;
|
|
||||||
|
|
||||||
FcmService._internal();
|
FcmService._internal();
|
||||||
|
|
||||||
static final FcmService _instance = FcmService._internal();
|
static final FcmService _instance = FcmService._internal();
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ class FcmUtils {
|
|||||||
|
|
||||||
static FcmUtils get instance => _instance;
|
static FcmUtils get instance => _instance;
|
||||||
|
|
||||||
|
static const String hashCodeKey = 'TeamMail';
|
||||||
|
|
||||||
StateChange? convertFirebaseDataMessageToStateChange(Map<String, dynamic> dataMessage) {
|
StateChange? convertFirebaseDataMessageToStateChange(Map<String, dynamic> dataMessage) {
|
||||||
log('FcmUtils::convertFirebaseDataMessageToStateChange():dataMessage: $dataMessage');
|
log('FcmUtils::convertFirebaseDataMessageToStateChange():dataMessage: $dataMessage');
|
||||||
Map<String, dynamic> mapData;
|
Map<String, dynamic> mapData;
|
||||||
@@ -73,4 +75,12 @@ class FcmUtils {
|
|||||||
bool isEmpty(dynamic object) {
|
bool isEmpty(dynamic object) {
|
||||||
return object == null || (object is String && object.isEmpty);
|
return object == null || (object is String && object.isEmpty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String hashTokenToDeviceId(String token) {
|
||||||
|
final deviceId = '$hashCodeKey-$token';
|
||||||
|
log('FcmUtils::hashCodeTokenToDeviceId():deviceId: $deviceId');
|
||||||
|
final deviceIdHashed = deviceId.hashCode.toString();
|
||||||
|
log('FcmUtils::hashCodeTokenToDeviceId():deviceIdHashCoded: $deviceIdHashed');
|
||||||
|
return deviceIdHashed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user