/
opt
/
canhelp
/
apps
/
mobile
/
lib
/
services
/
/opt/canhelp/apps/mobile/lib/services
mkdir
upload
Name
Size
Mode
Actions
api_client.dart
59021
0644
edit
dl
rm
push_service.dart
4495
0644
edit
dl
rm
storage_service.dart
9090
0644
edit
dl
rm
Edit:
/opt/canhelp/apps/mobile/lib/services/push_service.dart
(4495B)
import 'dart:async'; import 'dart:io' show Platform; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; import '../providers/auth_provider.dart'; import 'api_client.dart'; import 'storage_service.dart'; typedef PushMessageHandler = void Function(Map<String, String> data); @pragma('vm:entry-point') Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { try { await Firebase.initializeApp(); } catch (_) { // Firebase config may be missing in local/dev builds. } } class PushService { final ApiClient _api; final AuthProvider _auth; final StorageService _storage; PushMessageHandler? _onForegroundMessage; PushMessageHandler? _onMessageTap; StreamSubscription<String>? _tokenRefreshSub; StreamSubscription<RemoteMessage>? _onMessageSub; StreamSubscription<RemoteMessage>? _onMessageOpenedSub; bool _initialized = false; PushService({ required ApiClient api, required AuthProvider auth, required StorageService storage, }) : _api = api, _auth = auth, _storage = storage; Future<void> init({ PushMessageHandler? onForegroundMessage, PushMessageHandler? onMessageTap, }) async { if (_initialized) return; _initialized = true; _onForegroundMessage = onForegroundMessage; _onMessageTap = onMessageTap; try { await Firebase.initializeApp(); } catch (e) { debugPrint('PushService Firebase init skipped: $e'); return; } FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); final messaging = FirebaseMessaging.instance; await messaging.setAutoInitEnabled(true); try { await messaging.requestPermission(alert: true, badge: true, sound: true); } catch (e) { debugPrint('PushService permission request failed: $e'); } final initialToken = await messaging.getToken(); if (initialToken != null && initialToken.isNotEmpty) { await _saveAndSyncToken(initialToken); } _tokenRefreshSub = messaging.onTokenRefresh.listen((token) { _saveAndSyncToken(token); }); _onMessageSub = FirebaseMessaging.onMessage.listen( _handleForegroundMessage, ); _onMessageOpenedSub = FirebaseMessaging.onMessageOpenedApp.listen( _handleTapMessage, ); final initialMessage = await messaging.getInitialMessage(); if (initialMessage != null) { _handleTapMessage(initialMessage); } _auth.addListener(_onAuthChanged); await _syncStoredTokenIfAuthenticated(); } void dispose() { _auth.removeListener(_onAuthChanged); _tokenRefreshSub?.cancel(); _onMessageSub?.cancel(); _onMessageOpenedSub?.cancel(); } void _handleForegroundMessage(RemoteMessage message) { _onForegroundMessage?.call(_normalizePayload(message)); } void _handleTapMessage(RemoteMessage message) { _onMessageTap?.call(_normalizePayload(message)); } Map<String, String> _normalizePayload(RemoteMessage message) { final data = Map<String, String>.from(message.data); final title = message.notification?.title; final body = message.notification?.body; if (!data.containsKey('title') && title != null && title.isNotEmpty) { data['title'] = title; } if (!data.containsKey('body') && body != null && body.isNotEmpty) { data['body'] = body; } return data; } Future<void> _onAuthChanged() async { if (_auth.isAuthenticated) { await _syncStoredTokenIfAuthenticated(); } } Future<void> _saveAndSyncToken(String token) async { await _storage.savePushToken(token); if (_auth.isAuthenticated) { await _registerToken(token); } } Future<void> _syncStoredTokenIfAuthenticated() async { if (!_auth.isAuthenticated) return; final token = await _storage.getPushToken(); if (token == null || token.isEmpty) return; await _registerToken(token); } Future<void> _registerToken(String token) async { try { await _api.registerPushToken( token: token, platform: _platform(), locale: _auth.user?.locale, ); } catch (e) { debugPrint('PushService register token failed: $e'); } } String _platform() { if (kIsWeb) return 'web'; try { if (Platform.isAndroid) return 'android'; if (Platform.isIOS) return 'ios'; } catch (_) {} return 'unknown'; } }
Save
cmd:
run