Vue.js项目中如何将FCM后台消息存储到Vuex Store?
FCM背景消息同步到Vuex Store解决方案
错误根因
firebase-messaging-sw.js是Service Worker文件,运行在和Vue主应用完全隔离的独立线程中,无法直接访问主应用内的Vuex实例- Service Worker默认是classic脚本类型,原生不支持ES模块的
import语法,直接写导入语句必然触发语法错误
实现方案
采用postMessage通信机制完成Service Worker和主应用的跨上下文数据传递,步骤如下:
1. 修改Service Worker逻辑
调整firebase-messaging-sw.js中onBackgroundMessage回调,收到背景消息后向所有活跃的页面客户端发送通知:
importScripts('https://www.gstatic.com/firebasejs/9.0.1/firebase-app-compat.js'); importScripts('https://www.gstatic.com/firebasejs/9.0.1/firebase-messaging-compat.js'); var firebaseConfig = { // 你的配置项 }; firebase.initializeApp(firebaseConfig); const messaging = firebase.messaging(); messaging.onBackgroundMessage(function(payload) { // 匹配所有活跃的页面客户端 self.clients.matchAll({ includeUncontrolled: true, type: 'window' }).then(clients => { clients.forEach(client => { // 向页面发送标准化消息 client.postMessage({ type: 'FCM_BACKGROUND_MSG', data: payload }); }); }); });
2. 主应用监听消息并存入Vuex
在Vue主应用入口(如main.js、App.vue的mounted生命周期中)添加Service Worker消息监听,收到消息后调用Vuex接口存储:
import store from './store/store' // 页面加载完成后绑定监听 if ('serviceWorker' in navigator) { navigator.serviceWorker.addEventListener('message', (event) => { // 匹配FCM背景消息类型 if (event.data?.type === 'FCM_BACKGROUND_MSG') { // 根据你的Vuex定义调用对应mutation/action即可 store.commit('SAVE_FCM_MESSAGE', event.data.data) // 用action的写法:store.dispatch('saveFcmMessage', event.data.data) } }); }
3. 前台消息处理补充
用户正打开页面时收到的FCM前台消息,无需走Service Worker,直接在主应用的FCM初始化逻辑中监听onMessage事件即可直接操作Vuex:
// 主应用内FCM初始化完成后添加 messaging.onMessage((payload) => { store.commit('SAVE_FCM_MESSAGE', payload) })
额外说明
如果需要处理用户完全关闭页面时收到的FCM消息,可以在Service Worker中先把消息存入IndexedDB,等用户下次打开页面时,主应用主动向Service Worker拉取未同步的消息存入Vuex即可。
内容的提问来源于stack exchange,提问作者Ali Sohrabi
相关产品推荐
相关产品推荐

