如何解决Firebase Cloud Messaging推送通知发送失败问题
Firebase Cloud Messaging 推送通知错误修复方案
问题场景
通过Firebase Cloud Messaging(FCM)向移动设备发送推送通知时出现错误,错误截图如下:

相关代码片段:
public String pushNotificationFCM(ProfileDTO profileDTO, SigningTransactionDTO signingTransactionDTO) { FirebaseApp firebaseApp = null; try { ..... log.info(Constants.FCM_LOG_MESSAGE + ": proxy is disabled"); // 从类路径加载资源文件 Resource resource = new ClassPathResource(fcmKeyPath); // 从资源创建输入流 try (InputStream inputStream = resource.getInputStream()) { FirebaseOptions options = new FirebaseOptions.Builder() .setCredentials(GoogleCredentials.fromStream(inputStream)) .setServiceAccountId(fcmAccountService) .build(); if (FirebaseApp.getApps().isEmpty()) { firebaseApp = FirebaseApp.initializeApp(options); } else { firebaseApp = FirebaseApp.getApps().get(0); } log.info("Application initialized without proxy"); } } } catch (IOException e) { log.error(e.getMessage()); } try { response = FirebaseMessaging.getInstance(firebaseApp).send(message); } catch (FirebaseMessagingException e) { log.info(" Error " + response); }
修复方案
1. 校验Firebase凭证配置
- 确认服务账号密钥文件(
fcmKeyPath指向的文件)已正确放置在类路径下,且文件未损坏。检查文件内的JSON内容是否与Firebase项目生成的凭证一致。 - 除非明确需要,否则移除
setServiceAccountId(fcmAccountService)调用。多数情况下,服务账号ID会自动从凭证文件中提取,手动设置若值不正确会导致不匹配。
2. 修正FirebaseApp初始化逻辑
- 当前代码在嵌套try块内初始化
firebaseApp,如果外层try块的.....部分跳过了初始化逻辑,firebaseApp会保持null,调用FirebaseMessaging.getInstance(firebaseApp)时会抛出空指针异常。 - 重构代码,确保发送消息前
firebaseApp已完成初始化,示例调整如下:
public String pushNotificationFCM(ProfileDTO profileDTO, SigningTransactionDTO signingTransactionDTO) { FirebaseApp firebaseApp; try { // 初始化Firebase应用(未初始化时才执行) if (FirebaseApp.getApps().isEmpty()) { Resource resource = new ClassPathResource(fcmKeyPath); try (InputStream inputStream = resource.getInputStream()) { FirebaseOptions options = new FirebaseOptions.Builder() .setCredentials(GoogleCredentials.fromStream(inputStream)) .build(); firebaseApp = FirebaseApp.initializeApp(options); } log.info("无需代理,应用初始化完成"); } else { firebaseApp = FirebaseApp.getApps().get(0); } // 发送消息 String response = FirebaseMessaging.getInstance(firebaseApp).send(message); log.info("FCM消息发送成功:" + response); return response; } catch (IOException e) { log.error("加载Firebase凭证失败:" + e.getMessage(), e); } catch (FirebaseMessagingException e) { log.error("发送FCM消息失败:" + e.getMessage(), e); } return null; }
3. 优化错误处理逻辑
- 当前代码捕获
FirebaseMessagingException时,日志输出的response尚未赋值(因为发送调用失败),应改为记录异常的详细信息:
catch (FirebaseMessagingException e) { log.error("FCM发送失败:" + e.getMessage(), e); }
4. 检查网络连通性
- 确保服务器能够访问FCM的服务端点。如果处于受限网络环境,确认允许443端口的出站流量。
内容的提问来源于stack exchange,提问作者creative mark
相关产品推荐
相关产品推荐

