79 lines
2.4 KiB
Dart
79 lines
2.4 KiB
Dart
|
|
import 'package:firebase_core/firebase_core.dart';
|
||
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||
|
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||
|
|
import 'api_client.dart';
|
||
|
|
|
||
|
|
@pragma('vm:entry-point')
|
||
|
|
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||
|
|
await Firebase.initializeApp();
|
||
|
|
// VoIP pushes are handled natively by twilio_voice plugin.
|
||
|
|
// Other data messages can show a local notification if needed.
|
||
|
|
}
|
||
|
|
|
||
|
|
class PushNotificationService {
|
||
|
|
final ApiClient _api;
|
||
|
|
final FirebaseMessaging _messaging = FirebaseMessaging.instance;
|
||
|
|
final FlutterLocalNotificationsPlugin _localNotifications =
|
||
|
|
FlutterLocalNotificationsPlugin();
|
||
|
|
|
||
|
|
PushNotificationService(this._api);
|
||
|
|
|
||
|
|
Future<void> initialize() async {
|
||
|
|
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
|
||
|
|
|
||
|
|
await _messaging.requestPermission(
|
||
|
|
alert: true,
|
||
|
|
badge: true,
|
||
|
|
sound: true,
|
||
|
|
criticalAlert: true,
|
||
|
|
);
|
||
|
|
|
||
|
|
// Initialize local notifications
|
||
|
|
const androidSettings =
|
||
|
|
AndroidInitializationSettings('@mipmap/ic_launcher');
|
||
|
|
const initSettings = InitializationSettings(android: androidSettings);
|
||
|
|
await _localNotifications.initialize(initSettings);
|
||
|
|
|
||
|
|
// Get and register FCM token
|
||
|
|
final token = await _messaging.getToken();
|
||
|
|
if (token != null) {
|
||
|
|
await _registerToken(token);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Listen for token refresh
|
||
|
|
_messaging.onTokenRefresh.listen(_registerToken);
|
||
|
|
|
||
|
|
// Handle foreground messages (non-VoIP)
|
||
|
|
FirebaseMessaging.onMessage.listen(_handleForegroundMessage);
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> _registerToken(String token) async {
|
||
|
|
try {
|
||
|
|
await _api.dio.post('/fcm/register', data: {'fcm_token': token});
|
||
|
|
} catch (_) {}
|
||
|
|
}
|
||
|
|
|
||
|
|
void _handleForegroundMessage(RemoteMessage message) {
|
||
|
|
final data = message.data;
|
||
|
|
final type = data['type'];
|
||
|
|
|
||
|
|
// VoIP incoming_call is handled by twilio_voice natively
|
||
|
|
if (type == 'incoming_call') return;
|
||
|
|
|
||
|
|
// Show local notification for other types (missed call, queue alert, etc.)
|
||
|
|
_localNotifications.show(
|
||
|
|
message.hashCode,
|
||
|
|
data['title'] ?? 'TWP Softphone',
|
||
|
|
data['body'] ?? '',
|
||
|
|
const NotificationDetails(
|
||
|
|
android: AndroidNotificationDetails(
|
||
|
|
'twp_general',
|
||
|
|
'General Notifications',
|
||
|
|
importance: Importance.high,
|
||
|
|
priority: Priority.high,
|
||
|
|
),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|