Allow background sound notification
This commit is contained in:
+55
-8
@@ -11,23 +11,50 @@ import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'firebase_options.dart';
|
||||
import 'providers/profile_provider.dart';
|
||||
import 'models/profile.dart';
|
||||
|
||||
import 'app.dart';
|
||||
|
||||
import 'providers/notifications_provider.dart';
|
||||
import 'utils/app_time.dart';
|
||||
import 'utils/notification_permission.dart';
|
||||
import 'services/notification_service.dart';
|
||||
import 'services/notification_bridge.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
|
||||
// Initialize the plugin
|
||||
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
|
||||
/// Handle messages received while the app is terminated or in background.
|
||||
@pragma('vm:entry-point') // Required for background execution
|
||||
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
// Do minimal work in background isolate. Avoid initializing Flutter
|
||||
// plugins here (e.g. flutter_local_notifications) as that can hang
|
||||
// the background isolate and interfere with subsequent launches.
|
||||
// If you need to persist data from a background message, perform a
|
||||
// lightweight HTTP call or write to a background-capable DB.
|
||||
return;
|
||||
// 1. Initialize the plugin inside the background isolate
|
||||
final FlutterLocalNotificationsPlugin localNotifPlugin =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
|
||||
// 2. Extract title and body from the DATA payload (not message.notification)
|
||||
final String title = message.data['title'] ?? 'New Notification';
|
||||
final String body = message.data['body'] ?? 'You have a new update in TasQ.';
|
||||
|
||||
// Create a unique ID
|
||||
final int id = DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
||||
|
||||
// 3. Define the exact same channel specifics
|
||||
const androidDetails = AndroidNotificationDetails(
|
||||
'tasq_custom_sound_channel_2',
|
||||
'High Importance Notifications',
|
||||
importance: Importance.max,
|
||||
priority: Priority.high,
|
||||
playSound: true,
|
||||
sound: RawResourceAndroidNotificationSound('tasq_notification'),
|
||||
);
|
||||
|
||||
// 4. Show the notification manually
|
||||
await localNotifPlugin.show(
|
||||
id: id,
|
||||
title: title,
|
||||
body: body,
|
||||
notificationDetails: const NotificationDetails(android: androidDetails),
|
||||
payload: message.data['type'], // Or whatever payload you need for routing
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> main() async {
|
||||
@@ -97,6 +124,7 @@ Future<void> main() async {
|
||||
// request FCM permission (iOS/Android13+) and handle foreground messages
|
||||
await FirebaseMessaging.instance.requestPermission();
|
||||
}
|
||||
|
||||
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
||||
final notification = message.notification;
|
||||
if (notification != null) {
|
||||
@@ -122,6 +150,25 @@ Future<void> main() async {
|
||||
},
|
||||
);
|
||||
|
||||
// 1. Define the High Importance Channel (This MUST match your manifest exactly)
|
||||
const AndroidNotificationChannel channel = AndroidNotificationChannel(
|
||||
'tasq_custom_sound_channel', // id
|
||||
'High Importance Notifications', // title visible to user in phone settings
|
||||
description: 'This channel is used for important TasQ notifications.',
|
||||
importance:
|
||||
Importance.max, // THIS is what forces the sound and heads-up banner
|
||||
playSound: true,
|
||||
// 👇 Tell Android to use your specific file in the raw folder
|
||||
sound: RawResourceAndroidNotificationSound('tasq_notification'),
|
||||
);
|
||||
|
||||
// 2. Create the channel on the device
|
||||
await flutterLocalNotificationsPlugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin
|
||||
>()
|
||||
?.createNotificationChannel(channel);
|
||||
|
||||
// global navigator key used for snackbars/navigation from notification
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@ class NotificationService {
|
||||
|
||||
static final FlutterLocalNotificationsPlugin _plugin =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
static const String _channelId = 'tasq_default_channel';
|
||||
static const String _channelName = 'General';
|
||||
static const String _highChannelId = 'tasq_custom_sound_channel_2';
|
||||
static const String _highChannelName = 'High Priority';
|
||||
|
||||
/// Call during app startup, after any necessary permissions have been
|
||||
/// granted. The callback receives a [NotificationResponse] when the user
|
||||
@@ -19,6 +23,38 @@ class NotificationService {
|
||||
);
|
||||
const iosSettings = DarwinInitializationSettings();
|
||||
|
||||
// Ensure the Android notification channel exists with sound and vibration
|
||||
final androidImpl = _plugin
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin
|
||||
>();
|
||||
if (androidImpl != null) {
|
||||
const channel = AndroidNotificationChannel(
|
||||
_channelId,
|
||||
_channelName,
|
||||
description: 'General notifications for TasQ',
|
||||
importance: Importance.defaultImportance,
|
||||
playSound: true,
|
||||
enableVibration: true,
|
||||
);
|
||||
const highChannel = AndroidNotificationChannel(
|
||||
_highChannelId,
|
||||
_highChannelName,
|
||||
description: 'High priority notifications (sound + vibration)',
|
||||
importance: Importance.max,
|
||||
playSound: true,
|
||||
enableVibration: true,
|
||||
// 👇 Tell Android to use your specific file in the raw folder
|
||||
sound: RawResourceAndroidNotificationSound('tasq_notification'),
|
||||
);
|
||||
try {
|
||||
await androidImpl.createNotificationChannel(channel);
|
||||
} catch (_) {}
|
||||
try {
|
||||
await androidImpl.createNotificationChannel(highChannel);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
await _plugin.initialize(
|
||||
settings: const InitializationSettings(
|
||||
android: androidSettings,
|
||||
@@ -36,12 +72,17 @@ class NotificationService {
|
||||
String? payload,
|
||||
}) async {
|
||||
const androidDetails = AndroidNotificationDetails(
|
||||
'default_channel',
|
||||
'General',
|
||||
importance: Importance.high,
|
||||
_highChannelId,
|
||||
_highChannelName,
|
||||
importance: Importance.max,
|
||||
priority: Priority.high,
|
||||
playSound: true,
|
||||
enableVibration: true,
|
||||
sound: RawResourceAndroidNotificationSound('tasq_notification'),
|
||||
);
|
||||
const iosDetails = DarwinNotificationDetails(
|
||||
sound: 'tasq_notification.wav',
|
||||
);
|
||||
const iosDetails = DarwinNotificationDetails();
|
||||
await _plugin.show(
|
||||
id: id,
|
||||
title: title,
|
||||
|
||||
Reference in New Issue
Block a user