Firebase Firestore: Cannot call useEmulator() after instance has already been initialized

Viewed 1542

I am using Firebase Emulator Suite to test my Firebase Cloud Functions before deploying them into production.

Exploring this approach to trigger the callable firebase cloud functions from my Andriod device.

My App is crashing when I run it.

Error:

java.lang.IllegalStateException: Cannot call useEmulator() after instance has already been initialized.

Source of the error - FirebaseFirestore.java:

/**
   * Modifies this FirebaseDatabase instance to communicate with the Cloud Firestore emulator.
   *
   * <p>Note: Call this method before using the instance to do any database operations.
   *
   * @param host the emulator host (for example, 10.0.2.2)
   * @param port the emulator port (for example, 8080)
   */
  public void useEmulator(@NonNull String host, int port) {
    if (this.client != null) {
      throw new IllegalStateException(
          "Cannot call useEmulator() after instance has already been initialized.");
    }

    this.emulatorSettings = new EmulatedServiceSettings(host, port);
    this.settings = mergeEmulatorSettings(this.settings, this.emulatorSettings);
  }

Firestore is injected using the following method: (Using Hilt in my project)

@Provides
fun provideFirebaseFirestore(): FirebaseFirestore {

    val firebaseFirestoreSettings = FirebaseFirestoreSettings.Builder()
    firebaseFirestoreSettings.isPersistenceEnabled = false

    val firestore = FirebaseFirestore.getInstance()
    firestore.useEmulator("192.168.1.102", 8080)
    firestore.firestoreSettings = firebaseFirestoreSettings.build()

    return firestore
}

My doubt is useEmulator() in FirebaseFirestore.java is not a static method.
How can I call it before creating an instance of Firebase Firestore?

2 Answers

I have the same problem and the way I solved it wrap the firestore.useEmulator("192.168.1.102", 8080) in a try catch block like this

    try {
            firestore.useEmulator("192.168.1.102", 8080)
        } catch (e: IllegalStateException) {

        }

That could be because the Firebase state is kept between tests. The useEmulator is then called twice against the same firebase app instance, raising the error. At least, that was what happened to me during tests.

The approach to check a nested "host" property in the firestore instance -- described in this answer -- was what worked for me.

Related