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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 09:32:36