fix(notifications): handle deep linking on cold start without crash

This commit is contained in:
2026-04-21 17:57:53 +02:00
parent c92e2fb67f
commit 12011ce525
2 changed files with 20 additions and 11 deletions

View File

@@ -35,6 +35,7 @@ Future<void> initApp(EnvironmentEnum env) async {
initSfTracking();
configureAppRouter();
onRouterReady();
// TODO Fase 2: await initSentry(env);

View File

@@ -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;