fix(notifications): handle deep linking on cold start without crash
This commit is contained in:
@@ -35,6 +35,7 @@ Future<void> initApp(EnvironmentEnum env) async {
|
||||
initSfTracking();
|
||||
|
||||
configureAppRouter();
|
||||
onRouterReady();
|
||||
|
||||
// TODO Fase 2: await initSentry(env);
|
||||
|
||||
|
||||
@@ -6,15 +6,6 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:navigation/navigation.dart';
|
||||
import 'package:sf_app_platform/navigation/app_router.dart';
|
||||
|
||||
/// Background message handler. MUST be a top-level function annotated with
|
||||
/// `@pragma('vm:entry-point')` so the Flutter engine can dispatch it from a
|
||||
/// background isolate when the app is terminated or backgrounded.
|
||||
///
|
||||
/// This runs in a separate isolate: it CANNOT access main-isolate state
|
||||
/// (providers, GetIt, navigation). Keep it side-effect free or schedule work
|
||||
/// via shared_preferences. Do not call `Firebase.initializeApp` here —
|
||||
/// firebase_messaging 14+ auto-initializes the default app for the background
|
||||
/// isolate.
|
||||
@pragma('vm:entry-point')
|
||||
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
debugPrint('[FCM-bg] messageId: ${message.messageId}');
|
||||
@@ -30,6 +21,9 @@ const String _localChannelDescription =
|
||||
final FlutterLocalNotificationsPlugin _localNotifications =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
|
||||
Map<String, dynamic>? _pendingNotificationData;
|
||||
bool _routerReady = false;
|
||||
|
||||
Future<void> setupNotifications() async {
|
||||
final messaging = FirebaseMessaging.instance;
|
||||
|
||||
@@ -66,10 +60,19 @@ Future<void> setupNotifications() async {
|
||||
}
|
||||
}
|
||||
|
||||
void onRouterReady() {
|
||||
_routerReady = true;
|
||||
final pending = _pendingNotificationData;
|
||||
if (pending != null) {
|
||||
_pendingNotificationData = null;
|
||||
_handleNotificationNavigation(pending);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _initLocalNotifications() async {
|
||||
const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||
const iosInit = DarwinInitializationSettings(
|
||||
requestAlertPermission: false, // already requested via FirebaseMessaging
|
||||
requestAlertPermission: false,
|
||||
requestBadgePermission: false,
|
||||
requestSoundPermission: false,
|
||||
);
|
||||
@@ -83,7 +86,6 @@ Future<void> _initLocalNotifications() async {
|
||||
onDidReceiveNotificationResponse: _onLocalNotificationTapped,
|
||||
);
|
||||
|
||||
// Android 8+ requires every notification to belong to a channel.
|
||||
const channel = AndroidNotificationChannel(
|
||||
_localChannelId,
|
||||
_localChannelName,
|
||||
@@ -153,6 +155,12 @@ void _onLocalNotificationTapped(NotificationResponse response) {
|
||||
}
|
||||
|
||||
void _handleNotificationNavigation(Map<String, dynamic> data) {
|
||||
if (!_routerReady) {
|
||||
_pendingNotificationData = data;
|
||||
debugPrint('[Notification] router not ready, queued for later');
|
||||
return;
|
||||
}
|
||||
|
||||
final currentLocation =
|
||||
appRouter.routerDelegate.currentConfiguration.uri.path;
|
||||
if (!currentLocation.startsWith(AppRoutes.legacyDashboard)) return;
|
||||
|
||||
Reference in New Issue
Block a user