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

Spring+React PWA Web Push实现及通知无提示问题求助

Spring后端向React PWA推送Web通知方案及Firebase推送问题修复

一、替代webpush-java的后端实现方案

1. Firebase Admin SDK(推荐,与前端Firebase集成统一)

官方维护,稳定性强,适合已使用Firebase前端的场景:

  • Maven依赖配置:
    <dependency>
        <groupId>com.google.firebase</groupId>
        <artifactId>firebase-admin</artifactId>
        <version>9.2.0</version> <!-- 替换为最新稳定版 -->
    </dependency>
    
  • 初始化配置:
    @Configuration
    public class FirebaseConfig {
        @Bean
        public FirebaseApp firebaseApp() throws IOException {
            try (FileInputStream serviceAccount = new FileInputStream("classpath:serviceAccountKey.json")) {
                FirebaseOptions options = FirebaseOptions.builder()
                        .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                        .build();
                return FirebaseApp.initializeApp(options);
            }
        }
    }
    
  • 推送发送逻辑:
    @Service
    public class PushService {
        private final FirebaseMessaging firebaseMessaging;
    
        public PushService(FirebaseMessaging firebaseMessaging) {
            this.firebaseMessaging = firebaseMessaging;
        }
    
        public void sendPush(String userToken, String title, String body) throws FirebaseMessagingException {
            Message message = Message.builder()
                    .setToken(userToken)
                    .setData(Map.of(
                            "title", title,
                            "body", body,
                            "tag", "event-notification"
                    ))
                    .build();
            firebaseMessaging.send(message);
        }
    }
    

2. 维护活跃的Web Push Java库:nl.martijndwars/web-push

无需依赖Firebase,直接基于Web Push协议实现:

  • Maven依赖配置:
    <dependency>
        <groupId>nl.martijndwars</groupId>
        <artifactId>web-push</artifactId>
        <version>5.1.1</version> <!-- 最新版 -->
    </dependency>
    
  • 核心推送代码:
    public class WebPushNotificationService {
        private final PushService pushService;
    
        public WebPushNotificationService() throws GeneralSecurityException, IOException {
            // 生成VAPID密钥对(前端需用公钥获取用户订阅)
            VapidDetails vapidDetails = new VapidDetails(
                    "mailto:your-support@example.com",
                    "YOUR_VAPID_PUBLIC_KEY",
                    "YOUR_VAPID_PRIVATE_KEY"
            );
            this.pushService = new PushService(vapidDetails);
        }
    
        public void sendNotification(PushSubscription subscription, String payload) throws IOException, GeneralSecurityException {
            pushService.send(subscription, payload);
        }
    }
    
    前端需先获取用户的PushSubscription对象,传给后端存储,后续用该对象推送。

二、Firebase推送无声音、振动的修复方案

你的通知能显示但无提醒,主要是以下几点问题及解决方法:

1. 强制使用data-only payload

如果后端推送包含notification字段,系统会直接接管通知展示,跳过onBackgroundMessage的自定义配置。后端要只传data字段:

// 后端发送的Message示例
Message message = Message.builder()
        .setToken(userToken)
        .setData(Map.of(
                "title", "事件提醒",
                "body", "您关注的事件已发生",
                "tag", "event-tag"
        ))
        .build();

2. 完善notificationOptions配置

添加声音参数,明确禁用静音:

messaging.onBackgroundMessage((payload) => {
    const notificationTitle = payload.data.title;
    const notificationOptions = {
        body: payload.data.body,
        tag: payload.data?.tag,
        renotify: true,
        requireInteraction: true,
        vibrate: [500, 200, 500, 200, 100, 200, 100],
        icon: './images/icons/icon-128x128.png',
        badge: './images/icons/icon-128x128.png',
        sound: 'default', // 使用系统默认通知音
        silent: false, // 明确设置非静音
        actions: [] // 可选,添加交互按钮
    };
    self.registration.showNotification(notificationTitle, notificationOptions);
});

自定义声音需确保音频文件在service worker作用域内,比如/sounds/alert.mp3,设置sound: '/sounds/alert.mp3'。

3. 确认权限与系统设置

  • 前端需请求通知权限:
    async function initNotifications() {
        const permission = await Notification.requestPermission();
        if (permission !== 'granted') {
            throw new Error('通知权限未授予');
        }
    }
    
  • 检查设备系统设置:确保设备全局通知声音、振动开启,且PWA应用的通知设置中单独允许声音和振动(部分安卓设备需单独配置)。

4. 验证service worker作用域

service worker文件需放在根目录(或通过scope参数指定正确范围),确保能捕获background message,且资源路径(icon、sound)相对于service worker的路径正确。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:36:11