React JS中如何从public文件夹调用src/App.js内的函数
如何从Firebase Service Worker调用React组件中的函数?
这个问题的核心在于:Service Worker运行在独立的后台线程,和你的React应用(主线程)属于完全隔离的执行上下文,所以直接在Service Worker里调用React组件内定义的callMe()函数是行不通的。我们需要通过postMessage API来实现两者之间的通信,具体方案如下:
步骤1:在React应用中监听Service Worker的消息
修改你的src/App.js,添加Service Worker注册逻辑和消息监听,当收到来自Service Worker的指定消息时,执行callMe()函数:
import { useEffect } from 'react'; import messaging from './firebase-init'; import './App.css'; function App () { function callMe() { console.log('Call me function called'); } useEffect(() => { // 监听来自Service Worker的消息 if ('serviceWorker' in navigator) { navigator.serviceWorker.addEventListener('message', (event) => { // 判断消息类型,执行对应函数 if (event.data.type === 'CALL_ME') { callMe(); } }); } // 注册Firebase消息推送的Service Worker navigator.serviceWorker.register('/firebase-messaging-sw.js') .then(registration => { console.log('Service Worker 注册成功:', registration); }) .catch(error => { console.error('Service Worker 注册失败:', error); }); }, []); return ( <div className="App"> <h1>Hello World</h1> </div> ); } export default App;
步骤2:修改Service Worker,发送消息到主线程
更新public/firebase-messaging-sw.js中的notificationclick事件处理逻辑,不再直接调用callMe(),而是向匹配到的客户端发送消息:
importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js'); self.addEventListener('notificationclick', function (event) { console.log('On notification click: ', event); event.notification.close(); event.waitUntil(clients.matchAll({ includeUncontrolled: true, type: "window", }).then(function (clientList) { console.log('********* clientList: ', clientList); let foundClient = false; for (var i = 0; i < clientList.length; i++) { var client = clientList[i]; if (client.url !== '' && 'focus' in client) { client.focus(); // 向主线程发送消息,触发callMe函数 client.postMessage({ type: 'CALL_ME' }); foundClient = true; break; } } // 如果没有找到已打开的客户端,打开新页面并发送消息 if (!foundClient) { clients.openWindow('/').then(newClient => { newClient?.postMessage({ type: 'CALL_ME' }); }); } })); }); const firebaseConfig = { apiKey: "API_KEY", authDomain: "AUTH_DOMAIN", projectId: "PROJECT_ID", storageBucket: "STORAGE_BUCKET", messagingSenderId: "SENDER_ID", appId: "APP_ID", measurementId: "MEASUREMENT_ID" }; // Initialize Firebase const initializedFirebaseApp = firebase.initializeApp(firebaseConfig); const messaging = firebase.messaging();
原理说明
Service Worker和主线程之间无法直接共享函数或变量,只能通过postMessage传递序列化的数据。我们通过约定一个消息类型(比如CALL_ME),让Service Worker在需要触发函数时发送该消息,主线程监听并响应,最终调用React组件内的callMe()函数。
内容的提问来源于stack exchange,提问作者Sadashiv M
相关产品推荐
相关产品推荐

