Spring Boot中FirebaseMessaging服务注入其他业务服务无法正常工作如何解决
Spring Boot集成Firebase推送无报错不生效问题
问题背景
我正尝试在Spring Boot应用中发送Firebase推送通知,首先按如下方式配置了FirebaseMessaging:
@Configuration class FirebaseConfig { var logger: Logger = LoggerFactory.getLogger(FirebaseConfig::class.java) @Value("\${app.firebase-config-file}") lateinit var firebaseConfigPath: String @Bean("firebaseMessaging") @Throws(IOException::class) fun firebaseMessaging(): FirebaseMessaging { val firebaseOptions = FirebaseOptions .builder() .setCredentials(GoogleCredentials.fromStream(ClassPathResource(firebaseConfigPath).inputStream)) .build() val app = FirebaseApp.initializeApp(firebaseOptions, "QInspect") logger.info("Firebase application has been initialized") return FirebaseMessaging.getInstance(app) } }
我封装了如下服务实现推送通知发送逻辑:
@Service class FirebaseNotificationService constructor( @Autowired val firebaseMessaging: FirebaseMessaging, @Autowired val mobileDeviceLogService: MobileDeviceLogService ) { private var logger: Logger = LoggerFactory.getLogger(FirebaseNotificationService::class.java) private val gson = Gson() fun sendNotification(token: String, title: String, body: String): Status { try { val notification = Notification .builder() .setTitle(title) .setBody(body) .build() val message = Message .builder() .setToken(token) .setNotification(notification) .build() firebaseMessaging.send(message) logger.info("Firebase Notification sent") return Status(Constants.ResponseCode.SUCCESS, "Success") } catch (e: Exception) { logger.error("Firebase Notification Failed: ${e.printStackTrace()}") } return Status(Constants.ResponseCode.EXCEPTION, "Failed") } }
通过Postman调用以下接口,可以正常发送推送通知:
@RequestMapping("/notification") @RestController class NotificationResource constructor(@Autowired val firebaseService: FirebaseNotificationService) { @RequestMapping(value = ["/message"], method = [RequestMethod.POST]) @ApiOperation(value = "Send firebase push notification with token", authorizations = [Authorization(value = "basic"), Authorization(value = "oauth2", scopes = [])]) @ResponseBody @Throws(FirebaseMessagingException::class) fun sendNotificationMsg(@RequestParam(value = "title", required = true) title: String, @RequestParam(value = "body", required = true) body: String): Status { val user = SessionUtil.getUser() return firebaseService.sendNotification(user.token, title, body) }
问题描述
尝试将FirebaseNotificationService注入到另一个服务中发送推送,没有任何报错但功能不生效,对应服务代码如下:
@Service @Transactional class MessageSubscriber { @Autowired var firebaseService: FirebaseNotificationService? = null fun sendPush() { firebaseService?.sendNotification("token", "Some Title", "Some body") } }
请问我遗漏了什么配置?
问题更新
已找到问题原因,属于个人疏忽:调用确实进入了FirebaseNotificationService,但之前未提及的用户token获取逻辑失败,执行了提前返回,对应代码如下:
val notificationToken = tokenService.getTopByUserId(user.uuid!!) ?: return Status(Constants.ResponseCode.FAILED, "User or token not found")
问题解答
根因确认
该问题和Firebase配置、Spring Bean注入逻辑无关,属于业务逻辑静默失败导致:
- Token查询分支为空时直接返回错误状态,没有走到Firebase消息发送逻辑
- 提前返回分支没有打印错误日志,所以出现无报错但推送不生效的现象
优化方案
- 补充错误日志,避免静默失败:在提前返回分支增加日志记录,方便后续排查问题
val notificationToken = tokenService.getTopByUserId(user.uuid!!) ?: run { logger.warn("查询用户推送token失败,用户ID:${user.uuid}") return Status(Constants.ResponseCode.FAILED, "User or token not found") }
- 优化注入写法,规避空安全问题:Kotlin项目中建议使用构造注入替代字段注入,避免空判断开销
@Service @Transactional class MessageSubscriber( private val firebaseService: FirebaseNotificationService ) { private val logger = LoggerFactory.getLogger(javaClass) fun sendPush() { val sendResult = firebaseService.sendNotification("token", "Some Title", "Some body") // 处理返回结果,记录异常状态 if (sendResult.code != Constants.ResponseCode.SUCCESS) { logger.warn("推送发送失败,错误原因:${sendResult.msg}") } } }
- 统一业务返回结果处理逻辑,对所有非成功状态的返回统一增加日志埋点,避免后续再出现类似静默失败的问题。
内容的提问来源于stack exchange,提问作者Shailendra Madda
相关产品推荐
相关产品推荐

