feat(notifications): register FCM token with backend post-login
Adds NotificationsRemoteDatasource in sf_shared that POSTs the current Firebase Messaging token to /notifications/push, wired into the legacy login flow right after getUserInfo so the device can receive targeted push notifications. Fire-and-forget with catchError so a failure never blocks login.
This commit is contained in:
@@ -19,6 +19,7 @@ class LegacyLoginViewModel extends Notifier<LegacyLoginViewState>
|
||||
with LoginFormValidation {
|
||||
late final LegacyLoginRepository _repository;
|
||||
late final GetUserInfoUseCase _getUserInfoUseCase;
|
||||
late final NotificationsRemoteDatasource _notifications;
|
||||
late final SfTrackingRepository _tracking;
|
||||
|
||||
late final TextEditingController emailController;
|
||||
@@ -32,6 +33,7 @@ class LegacyLoginViewModel extends Notifier<LegacyLoginViewState>
|
||||
LegacyLoginViewState build() {
|
||||
_repository = ref.read(legacyLoginRepositoryProvider);
|
||||
_getUserInfoUseCase = ref.read(getUserInfoUseCaseProvider);
|
||||
_notifications = ref.read(notificationsRemoteDatasourceProvider);
|
||||
_tracking = ref.read(sfTrackingProvider);
|
||||
|
||||
emailController = TextEditingController();
|
||||
@@ -224,6 +226,12 @@ class LegacyLoginViewModel extends Notifier<LegacyLoginViewState>
|
||||
|
||||
if (!ref.mounted) return;
|
||||
|
||||
unawaited(
|
||||
_notifications.registerCurrentPushToken().catchError((Object e) {
|
||||
debugPrint('[FCM] failed to register push token post-login: $e');
|
||||
}),
|
||||
);
|
||||
|
||||
final hasDevices = await _repository.hasDevices();
|
||||
|
||||
if (!ref.mounted) return;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -29,6 +29,9 @@ export 'src/providers/user_info_provider.dart';
|
||||
export 'src/domain/repositories/user_repository.dart';
|
||||
export 'src/data/repositories/user_repository_impl.dart';
|
||||
export 'src/data/datasource/user_remote_datasource_impl.dart';
|
||||
export 'src/data/datasource/notifications_remote_datasource.dart';
|
||||
export 'src/data/datasource/notifications_remote_datasource_impl.dart';
|
||||
export 'src/providers/notifications_remote_datasource_provider.dart';
|
||||
export 'src/domain/entities/beneficiary_validation_entity.dart';
|
||||
export 'src/domain/entities/transaction_beneficiary_entity.dart';
|
||||
export 'src/data/models/payout_beneficiary_model.dart';
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
abstract class NotificationsRemoteDatasource {
|
||||
Future<void> registerCurrentPushToken();
|
||||
Future<void> registerPushToken(String token);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
import 'notifications_remote_datasource.dart';
|
||||
|
||||
class NotificationsRemoteDatasourceImpl implements NotificationsRemoteDatasource {
|
||||
NotificationsRemoteDatasourceImpl(this._repository);
|
||||
|
||||
final SaveFamilyRepository _repository;
|
||||
|
||||
@override
|
||||
Future<void> registerCurrentPushToken() async {
|
||||
final token = await FirebaseMessaging.instance.getToken();
|
||||
if (token == null || token.isEmpty) return;
|
||||
await registerPushToken(token);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> registerPushToken(String token) async {
|
||||
try {
|
||||
await _repository.post<Map<String, dynamic>>(
|
||||
'/notifications/push',
|
||||
body: <String, dynamic>{'token': token},
|
||||
);
|
||||
} on DioException catch (error) {
|
||||
final apiMsg = error.response?.data;
|
||||
final msg = apiMsg is String
|
||||
? apiMsg
|
||||
: (error.message ?? 'Error registering push token');
|
||||
throw Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:sf_shared/src/data/datasource/notifications_remote_datasource.dart';
|
||||
import 'package:sf_shared/src/data/datasource/notifications_remote_datasource_impl.dart';
|
||||
|
||||
final notificationsRemoteDatasourceProvider =
|
||||
Provider<NotificationsRemoteDatasource>((ref) {
|
||||
final saveFamilyRepository = GetIt.I<SaveFamilyRepository>();
|
||||
return NotificationsRemoteDatasourceImpl(saveFamilyRepository);
|
||||
});
|
||||
@@ -29,6 +29,7 @@ dependencies:
|
||||
flutter_svg: ^2.2.2
|
||||
flutter_riverpod: ^3.0.3
|
||||
dio: ^5.9.2
|
||||
firebase_messaging: ^16.1.3
|
||||
freezed_annotation: ^3.1.0
|
||||
freezed: ^3.2.3
|
||||
json_annotation: ^4.9.0
|
||||
|
||||
Reference in New Issue
Block a user