You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web推送通知:运行main.dart时onMessage监听器失效求助

Flutter Web 集成Firebase推送通知双正常解决方案

核心问题本质

Firebase Service Worker(firebase-messaging-sw.js)与Flutter Web初始化逻辑冲突:直接通过JS初始化Firebase会占用Service Worker,导致Flutter Web资源无法加载;单独启动Flutter时,因未正确注册Firebase Service Worker或初始化消息服务,推送功能失效。

分步解决方案

1. 同步Firebase配置到JS与Dart端

  • 在web/index.html的<head>中保留Firebase基础初始化,不要直接初始化消息服务:
    <script type="module">
      import { initializeApp } from "https://www.gstatic.com/firebasejs/9.23.0/firebase-app.js";
      const firebaseConfig = {
        apiKey: "YOUR_API_KEY",
        authDomain: "YOUR_AUTH_DOMAIN",
        projectId: "YOUR_PROJECT_ID",
        storageBucket: "YOUR_STORAGE_BUCKET",
        messagingSenderId: "YOUR_SENDER_ID",
        appId: "YOUR_APP_ID"
      };
      const app = initializeApp(firebaseConfig);
    </script>
    
  • 在main.dart中初始化Firebase核心与消息服务:
    import 'package:firebase_core/firebase_core.dart';
    import 'package:firebase_messaging/firebase_messaging.dart';
    import 'package:flutter/material.dart';
    
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      // 初始化Firebase核心
      await Firebase.initializeApp(
        options: const FirebaseOptions(
          apiKey: "YOUR_API_KEY",
          authDomain: "YOUR_AUTH_DOMAIN",
          projectId: "YOUR_PROJECT_ID",
          storageBucket: "YOUR_STORAGE_BUCKET",
          messagingSenderId: "YOUR_SENDER_ID",
          appId: "YOUR_APP_ID",
        ),
      );
      // 请求用户通知权限
      await FirebaseMessaging.instance.requestPermission();
      runApp(const MyApp());
    }
    

2. 兼容Flutter的Service Worker配置

将firebase-messaging-sw.js放在web目录下,添加Flutter路由兼容逻辑:

importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-messaging-compat.js');

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID"
};

firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();

// 处理后台推送消息
messaging.onBackgroundMessage(function(payload) {
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
    icon: '/icons/icon-192x192.png'
  };
  return self.registration.showNotification(notificationTitle, notificationOptions);
});

// 兼容Flutter页面路由
self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    event.respondWith(fetch('/index.html'));
  }
});

在index.html中Flutter初始化脚本前注册该Service Worker:

<script>
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
      navigator.serviceWorker.register('/firebase-messaging-sw.js')
        .then((registration) => {
          console.log('ServiceWorker 注册成功: ', registration.scope);
        }).catch((err) => {
          console.log('ServiceWorker 注册失败: ', err);
        });
    });
  }
</script>

3. Dart端处理前台推送消息

在页面组件中监听前台消息,确保应用在前台时能接收通知:

@override
void initState() {
  super.initState();
  // 监听前台推送消息
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    RemoteNotification? notification = message.notification;
    if (notification != null) {
      showDialog(
        context: context,
        builder: (_) => AlertDialog(
          title: Text(notification.title!),
          content: Text(notification.body!),
        ),
      );
    }
  });
}

4. 构建与部署注意事项

  • 开发测试时使用flutter run -d chrome --web-port=5000,生产环境执行flutter build web --release。
  • 确保Firebase控制台已配置Web应用的推送证书(Web Push certificates)。
  • 部署需使用HTTPS环境(本地可借助firebase serve测试)。

验证流程

  1. 构建并部署Web应用,打开后检查控制台是否有Service Worker注册成功日志。
  2. 从Firebase控制台发送测试推送,确认前台、后台均能收到通知,同时Flutter页面正常显示。

内容的提问来源于stack exchange,提问作者Muhammad Umair Saqib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 04:18:23