Flutter Firebase Messaging:点击通知跳转非栈顶聊天页
实现Firebase推送通知点击时的智能导航(仅当聊天页不在栈顶时打开)
针对你的需求——用户点击Firebase推送的消息通知时,仅当目标聊天页不在导航栈顶部才打开该页面,我们可以通过检查当前导航栈的顶部路由信息,避免重复入栈。
修改后的完整代码
void _handleMessage(RemoteMessage? message) { if (message == null) return; final context = navigatorKey.currentContext; if (context == null) return; String? storeId = message.data['storeId']; if (storeId == null) return; // 解析消息数据与对应店铺模型 MessageModel messageModel = MessageModel.fromJson(message.data); StoreModel? model = ProviderCalls.storePF(context) .stores .cast<StoreModel>() .firstWhere( (p0) => p0.id == messageModel.storeId, orElse: () => null, ); if (model == null) return; // 检查当前导航栈顶部是否已是目标聊天页 final navigator = Navigator.of(context); bool isTargetChatOnTop = false; if (navigator.canPop()) { final topRoute = navigator.route; // 方式1:通过命名路由+参数判断(推荐) if (topRoute.settings.name == "store_chat_screen") { // 替换成你的StoreChatScreen路由名称 final routeArgs = topRoute.settings.arguments as Map<String, dynamic>?; if (routeArgs?['storeId'] == storeId) { isTargetChatOnTop = true; } } // 方式2:若未使用命名路由,可通过页面实例判断(需自定义路由或RouteObserver支持) // 示例:if (topRoute is MaterialPageRoute && topRoute.builder(context) is StoreChatScreen) { // final chatScreen = topRoute.builder(context) as StoreChatScreen; // if (chatScreen.storeModel.id == storeId) isTargetChatOnTop = true; // } } // 仅当栈顶不是目标聊天页时,才跳转 if (!isTargetChatOnTop) { AppRoutes.push( context, StoreChatScreen( storeModel: model, userId: _getUserId(model, messageModel), ), ); } }
关键逻辑说明
- 导航栈状态检查:通过
Navigator.of(context)获取导航器实例,判断当前栈顶路由是否为目标聊天页 - 路由匹配判断:
- 推荐使用命名路由+参数的方式:通过路由名称确认页面类型,再对比参数中的
storeId是否与消息中的一致,这种方式稳定性更高 - 若未使用命名路由,可通过判断页面实例类型+实例参数的方式,但需要确保路由栈能获取到页面实例(可借助
RouteObserver实现)
- 推荐使用命名路由+参数的方式:通过路由名称确认页面类型,再对比参数中的
- 避免重复跳转:只有当栈顶不是目标聊天页时,才执行
push操作,防止同一聊天页多次入栈
注意事项
- 确保你的路由配置中,
StoreChatScreen的命名路由名称和参数传递逻辑统一 - 测试时需覆盖两种场景:聊天页在栈顶时点击通知不跳转,不在栈顶时正常打开聊天页
内容的提问来源于stack exchange,提问作者Amr Hassan
相关产品推荐
相关产品推荐

