Kotlin SpringBoot后端调用FCM报401 Unauthorized但可操作Firestore
在Kotlin SpringBoot后端中尝试发送FCM消息,目前能够成功查询、写入Firestore文档,但调用FCM发送消息时出现401 Unauthorized错误:
message: "handleException /
com.google.api.client.http.HttpResponseException: 401 Unauthorized
POST https://fcm.googleapis.com/v1/projects//messages:send"
服务账号已配置Firebase Admin和Firebase Cloud Messaging Admin角色,触发代码如下:
package cloudcode.features.firebase import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.Message import org.springframework.stereotype.Service @Service class FcmService { fun sendDataMessage(token: String, data: Map<String, String>) { val message = Message.builder() .setToken(token) .putAllData(data) .build() FirebaseMessaging.getInstance().send(message) } }
不清楚遗漏了什么配置,请求帮助。
以下是几个可能的原因和对应的解决办法:
确认服务账号密钥文件配置正确
虽然Firestore能正常工作,但FCM可能因为密钥文件的权限范围或加载问题导致认证失败。确保SpringBoot项目中正确加载了Firebase服务账号的JSON密钥文件:- 在
application.properties或application.yml中配置密钥文件路径:firebase.config.path=classpath:service-account-key.json - 初始化FirebaseApp时指定该配置文件,确保初始化逻辑覆盖FCM的认证需求:
import com.google.firebase.FirebaseApp import com.google.firebase.FirebaseOptions import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import java.io.FileInputStream @Configuration class FirebaseConfig { @Bean fun firebaseApp(): FirebaseApp { val serviceAccount = FileInputStream("src/main/resources/service-account-key.json") val options = FirebaseOptions.builder() .setCredentials(com.google.firebase.auth.FirebaseCredentials.fromStream(serviceAccount)) .build() return FirebaseApp.initializeApp(options) } }
- 在
检查服务账号的权限绑定是否生效
即使配置了角色,可能存在权限未及时同步的情况。前往Google Cloud控制台:- 找到对应的服务账号,确认Firebase Cloud Messaging Admin角色已正确绑定,且没有被其他权限策略限制。
- 可尝试重新添加角色并等待5-10分钟让权限生效。
确认FCM API已启用
前往Google Cloud控制台的API库,搜索Firebase Cloud Messaging API,确保该API处于启用状态。Firestore正常工作不代表FCM API会自动启用。检查请求的项目ID是否匹配
错误信息中的<project-id>需要和服务账号密钥文件中的project_id字段完全一致,避免因项目ID不匹配导致认证失败。
内容的提问来源于stack exchange,提问作者user7888262

