我是 Firebase 新手,我们正在使用 Firebase admin sdk 构建一个 Spring Boot 项目,我们希望在其中向移动用户发送通知。
我构建了一个简单的类,能够成功向 FMS 发送通知。
我下载了 Firebase Emulator 并更改了代码以使用它。在意识到我们不需要模拟器后,我恢复了我的代码,现在我收到以下错误:
Caused by: com.google.api.client.http.HttpResponseException: 401 Unauthorized
POST https://fcm.googleapis.com/v1/projects/workmerk-eec65/messages:send
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
我很困惑,因为它使用具有相同 firebase json 文件的 postman 与 http 方法一起工作,但使用 admin sdk 会抛出此错误。所以我认为可以肯定地说它不是我的 firebase 配置,特别是因为它之前就可以工作。
也很困惑,因为它似乎只在我的机器上不起作用,而在我同事的机器上成功工作,即使手机接收它。 非常感谢您的帮助!
我相信我的程序仍在尝试使用模拟器进行身份验证,但我不太确定...... 我还相信我删除了 firebase 模拟器的所有痕迹(删除了文件夹并检查了全局环境变量)
这是我的配置类:
@Configuration
public class FirebaseConfig {
@Value("${firebase.config}")
private String firebaseConfigPath;
@Value("${firebase.useEmulator:false}")
private boolean useEmulator;
@PostConstruct
public void initialize() {
try {
InputStream serviceAccount = getClass().getClassLoader().getResourceAsStream(firebaseConfigPath);
if (serviceAccount == null) {
throw new RuntimeException("Firebase configuration file not found in classpath.");
}
FirebaseOptions.Builder optionsBuilder = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setProjectId("workmerk-eec65");
// if (useEmulator) {
// // Emulator configuration
// FirestoreOptions firestoreOptions = FirestoreOptions.newBuilder()
// .setEmulatorHost("localhost:8085")
// .build();
// optionsBuilder.setFirestoreOptions(firestoreOptions)
// .setCredentials(new EmulatorCredentials());
// }
FirebaseOptions options = optionsBuilder.build();
if (FirebaseApp.getApps().isEmpty()) {
FirebaseApp.initializeApp(options);
}
} catch (Exception e) {
throw new RuntimeException("Failed to initialize Firebase", e);
}
}
}
尝试更换
InputStream serviceAccount = getClass().getClassLoader().getResourceAsStream(firebaseConfigPath);
由
InputStream serviceAccount = IOUtils.toInputStream(firebaseConfigPath, StandardCharsets.UTF_8)
另外,在我的例子中,json 文件中已经提到了项目 id,如果它与您相同,您可能需要删除此 .setProjectId("workmerk-eec65")