Skip to content

Conversation

@AndreaDiazCorreia
Copy link
Member

@AndreaDiazCorreia AndreaDiazCorreia commented Feb 12, 2026

The root cause was MostroApp.navigatorKey not being wired into GoRouter — it created a separate GlobalKey, so the navigator context was always
null when handling notification taps.

Changes:

  • Wire MostroApp.navigatorKey into GoRouter
  • Add terminated-state launch detection via getNotificationAppLaunchDetails()
  • Navigate to trade detail after app initialization completes
  • Remove dead FCM tap handlers (FCM sends silent messages with no order ID, for now)
  • Remove background isolate notification init (can't handle taps from there)

Summary by CodeRabbit

  • Bug Fixes
    • Fixed notification navigation when the app launches from a closed state. Tapping a notification now correctly takes you to the relevant trade details.

…inated states

- Initialize notifications in background isolate for proper tap handling
- Add notification tap handlers for background and terminated app states
- Navigate to order detail screen when notification contains order_id
- Add fallback navigation to notifications screen when no order ID present
- Handle initial message when app launches from terminated state via notification
- Improve error handling and logging for navigation
Add mounted check after async getNotificationLaunchOrderId() call to prevent navigation on disposed widget when app is launched from notification tap.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Walkthrough

Introduces notification-driven app navigation for terminated state launches. When users tap a notification, the app fetches the notification's orderId and navigates directly to the corresponding trade detail page upon initialization.

Changes

Cohort / File(s) Summary
Notification Launch Handling
lib/core/app.dart
Added _notificationLaunchHandled flag and logic to detect app launch from notification tap, fetch orderId via background service, and navigate to /trade_detail/{orderId} after first frame.
Navigation Configuration
lib/core/app_routes.dart
Updated GoRouter navigatorKey to reference MostroApp.navigatorKey instead of creating a new GlobalKey().
Background Notification Service
lib/features/notifications/services/background_notification_service.dart
Added public getNotificationLaunchOrderId() method to retrieve notification payload on app launch. Enhanced _onNotificationTap with null checks, payload validation, trade detail navigation, and fallback to /notifications view.

Sequence Diagram

sequenceDiagram
    participant App as App Initialization
    participant Router as GoRouter
    participant BGService as Background<br/>Notification Service
    participant System as System Notification
    
    App->>Router: Router available?
    Router-->>App: navigatorKey ready
    App->>BGService: getNotificationLaunchOrderId()
    BGService->>System: Query notification launch details
    System-->>BGService: Notification payload (orderId)
    BGService-->>App: Return orderId (or null)
    alt Notification orderId present
        App->>Router: Navigate to /trade_detail/{orderId}
    else No notification
        App->>App: Mark handled, wait for user action
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • Catrya
  • grunch

Poem

🐰 A notification hops through the app,
When tapped, no details slip through the gap,
OrderId fetched with graceful care,
Trade details appear—navigation's fair! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: enabling push notification taps to navigate to the trade detail screen by wiring the navigator key into GoRouter and adding terminated-state launch detection.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/notification-deep-link-navigation

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
lib/core/app.dart (1)

164-175: Use logger instead of debugPrint.

Line 171 uses debugPrint for logging the notification navigation event. The rest of the notification service correctly uses the singleton logger instance.

Proposed fix
-              debugPrint('App launched from notification tap, navigating to order: $orderId');
+              logger.i('App launched from notification tap, navigating to order: $orderId');

This requires adding the logger import if not already present:

import 'package:mostro_mobile/services/logger_service.dart';

As per coding guidelines: "Always use the pre-configured singleton logger instance via import 'package:mostro_mobile/services/logger_service.dart'; and never directly instantiate Logger()."

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Catrya
Copy link
Member

Catrya commented Feb 12, 2026

When i test it only works well for notifications of these statuses: active: buyer-took-order, waiting-buyer-invoice: add-invoice
For notifications of these others, tapping them only takes me to the order book: fiatsent: fiatsent-ok, cooperative-cancel-initiated-by-peer, dispute: initiated-by-peer, success: purchase-completed

@grunch grunch requested a review from mostronator February 12, 2026 19:16
Copy link
Collaborator

@mostronator mostronator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Clean fix.

The root cause was clear: GoRouter was creating its own GlobalKey<NavigatorState>() instead of sharing MostroApp.navigatorKey, so currentContext was always null in notification tap handlers.

Key changes look correct:

  1. Navigator key wiringnavigatorKey: MostroApp.navigatorKey in createRouter()
  2. Terminated-state launchgetNotificationLaunchOrderId() via getNotificationAppLaunchDetails() handles cold-start from notification ✅
  3. _onNotificationTap logic — fixed inverted null check + properly routes to /trade_detail/$orderId when payload exists ✅
  4. _notificationLaunchHandled guard — prevents duplicate navigation on rebuilds ✅

The addPostFrameCallback in build is fine since it's gated by _notificationLaunchHandled flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants