AndroidDev
AndroidDev

Reputation: 928

Firebase Auth not getting initialized in spring boot

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

 public static void main(String[] args) {
    SpringApplication.run(InfanoApplication.class, args);

    try {
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();

        File file = new File(classloader.getResource("firebase2.json").getFile());
        logger.info("FILE PATH : " + file.getAbsolutePath());
        FileInputStream serviceAccount = new FileInputStream(file.getAbsolutePath());

        FirebaseOptions options = new FirebaseOptions.Builder()
                .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                .setDatabaseUrl(FB_BASE_URL)
                .build();

        firebaseApp = FirebaseApp.initializeApp(options);
        logger.info("FIREBASE NAME : "+firebaseApp.getName());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

In API code

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

ERROR:

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

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

Upvotes: 1

Views: 1678

Answers (1)

Shababb Karim
Shababb Karim

Reputation: 3713

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.

@Configuration
public class FirebaseConfig {

    //TODO: In your case maybe something else
    @Value(value = "classpath:serviceAccount.json")
    private Resource serviceAccountResource;

    @Bean
    public FirebaseApp createFireBaseApp() throws IOException {
        InputStream serviceAccount = serviceAccountResource.getInputStream();

        FirebaseOptions options = new FirebaseOptions.Builder()
                .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                .setDatabaseUrl("<db-url>")
                .setStorageBucket("<storage-url>")
                .build();

        //Add loggers
        System.out.println("Firebase config initialized");

        return FirebaseApp.initializeApp(options);
    }

    
    @Bean
    @DependsOn(value = "createFireBaseApp")
    public StorageClient createFirebaseStorage() {
        return StorageClient.getInstance();
    }

    @Bean
    @DependsOn(value = "createFireBaseApp")
    public FirebaseAuth createFirebaseAuth() {
        return FirebaseAuth.getInstance();
    }

    @Bean
    @DependsOn(value = "createFireBaseApp")
    public FirebaseDatabase createFirebaseDatabase() {
        return FirebaseDatabase.getInstance();
    }

    @Bean
    @DependsOn(value = "createFireBaseApp")
    public FirebaseMessaging createFirebaseMessaging() {
        return FirebaseMessaging.getInstance();
    }
}

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

@Service
class MyService {

    @Autowired
    private FirebaseAuth firebaseAuth;

    //TODO: Probably should have return type
    public void findUser(String mobile) {
        firebaseAuth.getUserByPhoneNumber(mobile);
    }
}

Upvotes: 4

Related Questions