Scenario
I am using the firebase_messaging package to handle notifications for my Flutter project. I have a Nested Navigation flow implemented, implementation similar to here.
Problem
I am able to handle notifications when the app is in the foreground or in the background, for nested navigation routes. However, I am facing difficulty handling notifications when the app is in the terminated state. I have tried following the Firebase documentation
Code
In my MaterialApp
widget in app.dart
, I’ve omitted the routes
parameter, and have populated the onGenerateRoute
parameter with:
NavigationService.dart
Route<dynamic> onGenerateRoute(RouteSettings settings) {
String path = settings.name!;
Object? arguments = settings.arguments;
if (settings.arguments == null) {
Uri uri = Uri.parse(settings.name!);
path = uri.path;
arguments = uri.queryParameters;
}
if (_appRoutes[path] != null) {
if (Platform.isIOS) {
return CupertinoPageRoute(
settings: settings,
builder: (_) => _appRoutes[path]!(arguments),
);
}
return MaterialPageRoute(
settings: settings,
builder: (_) => _appRoutes[path]!(arguments),
);
} else {
print('route: $path');
throw SystemException('onGenerateRoute: Route not found');
}
}
Each of my nested navigation services also contain their own implementation of onGenerateRoute
, which checks against specific routes that they contain.
When I attempt to navigate to a “nested route”, ie. /profile
, I get the following error message, even though my ProfileNavigationService
contains the route
I/flutter ( 8088): route: /profile
I/flutter ( 8088): onGenerateRoute: Route not found
I/flutter ( 8088): #0 NavigationService.onGenerateRoute (package:vibefam/routes/navigation_service.dart:359)
I/flutter ( 8088): #1 _WidgetsAppState._onGenerateRoute (package:flutter/src/widgets/app.dart:1482)
I/flutter ( 8088): #2 NavigatorState._routeNamed (package:flutter/src/widgets/navigator.dart:4447)
This is how I’ve set up my notification listeners:
Future<void> _setupNotificationHandler() async {
// handles interaction when app is terminated
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
_handleMessage(initialMessage);
}
// handles interaction when app is in the background
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
}
void _handleMessage(RemoteMessage message) {
String? parsedRoute = NotificationUtil.getRoute(message);
if (parsedRoute == null) {
return;
}
Uri uri = Uri.parse(parsedRoute);
String path = uri.path;
Map<String, dynamic> params = uri.queryParameters;
if (!NestedRouteHandler.hasNestedRoute(path)) {
NavigationService.of(context).navigateTo(path, arguments: params);
return;
}
NestedRouteHandler.navigate(context, path, params);
}
@override
void initState() {
super.initState();
_setupNotificationHandler();
}
skythefire is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.