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

如何将Firebase初始化配置传入Service Worker?

如何将主JS中的Firebase配置传入Service Worker

下面提供两种可行的实现方案,适配你封装库的需求:


方法1:通过postMessage传递配置并缓存存储

这种方式无需修改现有Service Worker的托管路径,通过消息传递把配置传给SW,SW将配置持久化存储后复用。

步骤1:修改主JS,注册SW后发送配置

在uponGrantedPermissionHandler的SW注册成功回调中,添加发送配置的逻辑:

function uponGrantedPermissionHandler(messaging,vapidKey,serviceWorkerUrl,tokenNotificationUrl,workerAsModule, firebaseConfig){
    if ('serviceWorker' in navigator) {
        const workerConfig = workerAsModule?{ type: 'module' }:undefined
        
        serviceWorkerUrl = serviceWorkerUrl??"https://mycdn.com/firebase-messaging-sw.js";

        navigator.serviceWorker
        .register(serviceWorkerUrl, workerConfig)
        .then((registration) => {
                if (registration) {
                    console.log('Registration successful, scope is:', registration.scope)
                    // 向Service Worker发送配置
                    registration.active.postMessage({
                        type: 'SET_FIREBASE_CONFIG',
                        config: firebaseConfig
                    });
                    getToken(messaging, { vapidKey })
                        .then((token)=>tokenHandle(token,tokenNotificationUrl))
                        .catch(error => console.error(error));
                }
            })
            .catch(function (err) {
                console.log('Service worker registration failed, error:', err)
            })
    }
}

同时修改pushNotificationInit中的调用,把firebaseConfig传入:

uponGrantedPermissionHandler(messaging,vapidKey,serviceWorkerUrl,tokenNotificationUrl,workerAsModule, firebaseConfig)

步骤2:修改Service Worker,接收并复用配置

调整SW脚本,先尝试从缓存读取配置,无配置则等待消息传递,再初始化Firebase:

import { initializeApp } from 'firebase/app';
import { onBackgroundMessage,getMessaging } from 'firebase/messaging/sw'

let firebaseConfig = null;

// 从缓存加载配置
async function loadFirebaseConfig() {
  const cache = await caches.open('firebase-config-cache');
  const configRes = await cache.match('firebase-config');
  if (configRes) {
    firebaseConfig = await configRes.json();
    initFirebase();
  }
}

// 初始化Firebase并监听后台消息
function initFirebase() {
  if (!firebaseConfig) return;
  const app = initializeApp(firebaseConfig);
  const messaging = getMessaging(app);

  onBackgroundMessage(messaging, (payload) => {
    console.log('[firebase-messaging-sw.js] Received background message ', payload);
      
    const notificationTitle = payload.notification.title || 'Background Message Title';
    const notificationOptions = {
      body: payload.notification.body || 'Background message body',
      icon: 'icon.png'
    };
      
    self.registration.showNotification(notificationTitle, notificationOptions);
  });
}

// 监听消息,接收并存储配置
self.addEventListener('message', async (event) => {
  if (event.data.type === 'SET_FIREBASE_CONFIG') {
    firebaseConfig = event.data.config;
    // 将配置存入缓存
    const cache = await caches.open('firebase-config-cache');
    await cache.put('firebase-config', new Response(JSON.stringify(firebaseConfig)));
    initFirebase();
  }
});

// 页面加载时先尝试读取缓存
loadFirebaseConfig();

方法2:动态生成Service Worker脚本(更适合库封装)

这种方式无需提前托管SW脚本,直接在主JS中生成包含用户配置的SW代码,再注册使用。

修改主JS的uponGrantedPermissionHandler函数

function uponGrantedPermissionHandler(messaging,vapidKey,serviceWorkerUrl,tokenNotificationUrl,workerAsModule, firebaseConfig){
    if ('serviceWorker' in navigator) {
        // 动态生成包含配置的Service Worker代码
        const swCode = `
import { initializeApp } from 'firebase/app';
import { onBackgroundMessage,getMessaging } from 'firebase/messaging/sw'

const firebaseConfig = ${JSON.stringify(firebaseConfig)};

const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);

onBackgroundMessage(messaging, (payload) => {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
    
  const notificationTitle = payload.notification.title || 'Background Message Title';
  const notificationOptions = {
    body: payload.notification.body || 'Background message body',
    icon: 'icon.png'
  };
    
  self.registration.showNotification(notificationTitle, notificationOptions);
});
        `;
        // 创建Blob URL用于注册SW
        const blob = new Blob([swCode], { type: 'application/javascript' });
        const swUrl = URL.createObjectURL(blob);

        const workerConfig = workerAsModule?{ type: 'module' }:undefined

        navigator.serviceWorker
        .register(swUrl, workerConfig)
        .then((registration) => {
                console.log('Registration successful, scope is:', registration.scope)
                getToken(messaging, { vapidKey })
                    .then((token)=>tokenHandle(token,tokenNotificationUrl))
                    .catch(error => console.error(error));
                // 释放Blob URL资源
                URL.revokeObjectURL(swUrl);
            })
            .catch(function (err) {
                console.log('Service worker registration failed, error:', err)
                URL.revokeObjectURL(swUrl);
            })
    }
}

同样需要修改pushNotificationInit中的调用,传入firebaseConfig参数。


两种方案对比

  • 方法1:适合已有固定SW托管地址的场景,配置持久化存储,SW重启后可直接读取,无需重复传递。
  • 方法2:灵活性更高,无需用户额外托管SW文件,适合封装成通用库,但每次注册会生成新的Blob URL,需注意SW更新逻辑。

内容的提问来源于stack exchange,提问作者Dimitrios Desyllas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:32:35