Firebase Auth在Spring Boot中未能初始化

huangapple go评论119阅读模式
英文:

Firebase Auth not getting initialized in spring boot

问题

我在我的Spring Boot应用程序(API应用程序)中使用Firebase Admin SDK。

在IntelliJ中本地运行时,一切正常。但是在部署到Tomcat时,出现空指针异常(NPE)。

在Spring Boot应用程序中:

  1. public static void main(String[] args) {
  2. SpringApplication.run(InfanoApplication.class, args);
  3. try {
  4. ClassLoader classloader = Thread.currentThread().getContextClassLoader();
  5. File file = new File(classloader.getResource("firebase2.json").getFile());
  6. logger.info("FILE PATH : " + file.getAbsolutePath());
  7. FileInputStream serviceAccount = new FileInputStream(file.getAbsolutePath());
  8. FirebaseOptions options = new FirebaseOptions.Builder()
  9. .setCredentials(GoogleCredentials.fromStream(serviceAccount))
  10. .setDatabaseUrl(FB_BASE_URL)
  11. .build();
  12. firebaseApp = FirebaseApp.initializeApp(options);
  13. logger.info("FIREBASE NAME : " + firebaseApp.getName());
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. }
  17. }

在API代码中:

  1. userRecord = FirebaseAuth.getInstance(InfanoApplication.firebaseApp).getUserByPhoneNumber(mobile);

错误信息:

  1. java.lang.NullPointerException
  2. at com.google.firebase.ImplFirebaseTrampolines.getService(ImplFirebaseTrampolines.java:62)
  3. at com.google.firebase.auth.FirebaseAuth.getInstance(FirebaseAuth.java:101)

有人能帮忙解决这个问题吗?提前谢谢。

英文:

I am using firebase admin sdk in my spring boot app. (API app)

When I run locally in intelliJ its working fine. But when deployed in tomcat its giving me NPE.

In Springboot application

  1. public static void main(String[] args) {
  2. SpringApplication.run(InfanoApplication.class, args);
  3. try {
  4. ClassLoader classloader = Thread.currentThread().getContextClassLoader();
  5. File file = new File(classloader.getResource("firebase2.json").getFile());
  6. logger.info("FILE PATH : " + file.getAbsolutePath());
  7. FileInputStream serviceAccount = new FileInputStream(file.getAbsolutePath());
  8. FirebaseOptions options = new FirebaseOptions.Builder()
  9. .setCredentials(GoogleCredentials.fromStream(serviceAccount))
  10. .setDatabaseUrl(FB_BASE_URL)
  11. .build();
  12. firebaseApp = FirebaseApp.initializeApp(options);
  13. logger.info("FIREBASE NAME : "+firebaseApp.getName());
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. }
  17. }

In API code

  1. userRecord = FirebaseAuth.getInstance(InfanoApplication.firebaseApp).getUserByPhoneNumber(mobile);

ERROR:

  1. java.lang.NullPointerException
  2. at com.google.firebase.ImplFirebaseTrampolines.getService(ImplFirebaseTrampolines.java:62)
  3. at com.google.firebase.auth.FirebaseAuth.getInstance(FirebaseAuth.java:101)

Can someone help in fixing this issue. Thank you in advance.

答案1

得分: 4

你不应该在主方法中像这样创建 Firebase 的实例。很可能你的服务账户没有在正确的类路径中被找到。我会创建一个 Spring 配置,在应用程序启动时创建一个 Firebase 应用。我已经将我的服务账户放在 resources 文件夹的根目录下。

  1. @Configuration
  2. public class FirebaseConfig {
  3. //TODO: 在你的情况下可能会有其他配置
  4. @Value(value = "classpath:serviceAccount.json")
  5. private Resource serviceAccountResource;
  6. @Bean
  7. public FirebaseApp createFireBaseApp() throws IOException {
  8. InputStream serviceAccount = serviceAccountResource.getInputStream();
  9. FirebaseOptions options = new FirebaseOptions.Builder()
  10. .setCredentials(GoogleCredentials.fromStream(serviceAccount))
  11. .setDatabaseUrl("<db-url>")
  12. .setStorageBucket("<storage-url>")
  13. .build();
  14. //添加日志记录
  15. System.out.println("Firebase 配置已初始化");
  16. return FirebaseApp.initializeApp(options);
  17. }
  18. @Bean
  19. @DependsOn(value = "createFireBaseApp")
  20. public StorageClient createFirebaseStorage() {
  21. return StorageClient.getInstance();
  22. }
  23. @Bean
  24. @DependsOn(value = "createFireBaseApp")
  25. public FirebaseAuth createFirebaseAuth() {
  26. return FirebaseAuth.getInstance();
  27. }
  28. @Bean
  29. @DependsOn(value = "createFireBaseApp")
  30. public FirebaseDatabase createFirebaseDatabase() {
  31. return FirebaseDatabase.getInstance();
  32. }
  33. @Bean
  34. @DependsOn(value = "createFireBaseApp")
  35. public FirebaseMessaging createFirebaseMessaging() {
  36. return FirebaseMessaging.getInstance();
  37. }
  38. }

现在,如果我想在任何一个服务类中使用 Firebase Auth,我只需执行以下操作:

  1. @Service
  2. class MyService {
  3. @Autowired
  4. private FirebaseAuth firebaseAuth;
  5. //TODO: 可能应该有返回类型
  6. public void findUser(String mobile) {
  7. firebaseAuth.getUserByPhoneNumber(mobile);
  8. }
  9. }
英文:

You shouldn't create an instance of Firebase like this in the main method. Probably your service account is not being found in the proper classpath. I would create a Spring Configuration which creates a Firebase app on application startup. I have kept my service account in the root of resources folder.

  1. @Configuration
  2. public class FirebaseConfig {
  3. //TODO: In your case maybe something else
  4. @Value(value = &quot;classpath:serviceAccount.json&quot;)
  5. private Resource serviceAccountResource;
  6. @Bean
  7. public FirebaseApp createFireBaseApp() throws IOException {
  8. InputStream serviceAccount = serviceAccountResource.getInputStream();
  9. FirebaseOptions options = new FirebaseOptions.Builder()
  10. .setCredentials(GoogleCredentials.fromStream(serviceAccount))
  11. .setDatabaseUrl(&quot;&lt;db-url&gt;&quot;)
  12. .setStorageBucket(&quot;&lt;storage-url&gt;&quot;)
  13. .build();
  14. //Add loggers
  15. System.out.println(&quot;Firebase config initialized&quot;);
  16. return FirebaseApp.initializeApp(options);
  17. }
  18. @Bean
  19. @DependsOn(value = &quot;createFireBaseApp&quot;)
  20. public StorageClient createFirebaseStorage() {
  21. return StorageClient.getInstance();
  22. }
  23. @Bean
  24. @DependsOn(value = &quot;createFireBaseApp&quot;)
  25. public FirebaseAuth createFirebaseAuth() {
  26. return FirebaseAuth.getInstance();
  27. }
  28. @Bean
  29. @DependsOn(value = &quot;createFireBaseApp&quot;)
  30. public FirebaseDatabase createFirebaseDatabase() {
  31. return FirebaseDatabase.getInstance();
  32. }
  33. @Bean
  34. @DependsOn(value = &quot;createFireBaseApp&quot;)
  35. public FirebaseMessaging createFirebaseMessaging() {
  36. return FirebaseMessaging.getInstance();
  37. }
  38. }

Now if I want to use Firebase Auth in any of my service classes I would just do the following:

  1. @Service
  2. class MyService {
  3. @Autowired
  4. private FirebaseAuth firebaseAuth;
  5. //TODO: Probably should have return type
  6. public void findUser(String mobile) {
  7. firebaseAuth.getUserByPhoneNumber(mobile);
  8. }
  9. }

huangapple
  • 本文由 发表于 2020年8月26日 03:57:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63586220.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定