Flutter 2 集成 InAppWebView 与 Firebase Messaging:点击FCM通知打开应用后如何让WebView跳转至指定URL
解决FCM通知点击后InAppWebView跳转自定义URL的问题
看起来你已经完成了大部分配置,问题的核心在于:你只更新了状态变量,但没有主动触发WebView加载新的URL,另外还需要处理应用冷启动(完全关闭后点击通知打开)的场景。下面是具体的解决方案:
问题根源分析
你的代码中,setState(() { this.url = message.data['url']; })只是更新了状态变量,但InAppWebView的initialUrlRequest仅在组件第一次构建时生效,后续状态变更不会自动触发WebView重新加载。此外,onMessageOpenedApp仅处理应用处于后台时被通知唤醒的情况,完全关闭应用后的冷启动场景需要单独处理。
具体修改步骤
1. 统一URL状态变量
首先把代码中的URL变量统一,避免混淆,比如将webViewUrl和this.url合并为_currentUrl:
class _MyAppState extends State<MyApp> { ... String _currentUrl = "https://baseurl.com/"; // 统一为这个变量 ... }
2. 新增WebView加载URL的工具方法
添加一个专门的方法来处理URL加载,既更新状态变量,又通过WebViewController主动触发加载:
void _loadTargetUrl(String targetUrl) { setState(() { _currentUrl = targetUrl; }); // 确保WebViewController已初始化,再执行加载 if (webViewController != null) { webViewController!.loadUrl( urlRequest: URLRequest(url: Uri.parse(targetUrl)), ); } }
3. 完善FCM消息监听逻辑
修改initState中的监听代码,同时处理后台唤醒和冷启动两种场景:
@override void initState() { super.initState(); ... // 处理冷启动:应用完全关闭后,点击通知打开的情况 FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) { if (message != null && message.data['url'] != null) { print('# Cold start message dataUrl: ${message.data['url']}'); _loadTargetUrl(message.data['url']); } }); // 处理后台唤醒:应用在后台运行时,点击通知打开的情况 FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { print('# onMessage Listen message title: ${message.notification?.title}'); print('# onMessage Listen message body: ${message.notification?.body}'); print('# onMessage Listen message dataUrl: ${message.data['url']}'); if (message.data['url'] != null) { _loadTargetUrl(message.data['url']); } }); ... }
4. 更新WebView的初始URL配置
将InAppWebView的initialUrlRequest改为使用状态变量_currentUrl,确保冷启动时能直接加载通知中的URL:
InAppWebView( key: webViewKey, initialUrlRequest: URLRequest(url: Uri.parse(_currentUrl)), // 这里修改为_currentUrl initialOptions: options, pullToRefreshController: pullToRefreshController, onWebViewCreated: (controller) { webViewController = controller; // 如果冷启动时已经有目标URL,这里可以再触发一次加载(防止控制器初始化晚于消息处理) if (_currentUrl != "https://baseurl.com/") { controller.loadUrl( urlRequest: URLRequest(url: Uri.parse(_currentUrl)), ); } }, ... )
测试验证
修改完成后,重新打包测试:
- 后台运行时点击通知:WebView应自动跳转到目标URL
- 完全关闭应用后点击通知:应用启动后WebView直接加载目标URL
- 前台接收消息:不影响原有逻辑
内容的提问来源于stack exchange,提问作者Jaehyuk Choi
相关产品推荐
相关产品推荐

