diff --git a/src/main/java/com/google/firebase/FirebaseApp.java b/src/main/java/com/google/firebase/FirebaseApp.java index 27727c366..95c1a34a2 100644 --- a/src/main/java/com/google/firebase/FirebaseApp.java +++ b/src/main/java/com/google/firebase/FirebaseApp.java @@ -223,6 +223,7 @@ static FirebaseApp initializeApp(FirebaseOptions options, String name, !instances.containsKey(normalizedName), "FirebaseApp name " + normalizedName + " already exists!"); + overrideProcessEnvironment(options); FirebaseApp firebaseApp = new FirebaseApp(normalizedName, options, tokenRefresherFactory); instances.put(normalizedName, firebaseApp); return firebaseApp; @@ -583,4 +584,8 @@ private static FirebaseOptions getOptionsFromEnvironment() throws IOException { builder.setCredentials(APPLICATION_DEFAULT_CREDENTIALS); return builder.build(); } + + private static void overrideProcessEnvironment(FirebaseOptions options) { + options.getProcessEnvironmentOverride().forEach(FirebaseProcessEnvironment::setenv); + } } diff --git a/src/main/java/com/google/firebase/FirebaseOptions.java b/src/main/java/com/google/firebase/FirebaseOptions.java index 8e7a29ccb..a99df752e 100644 --- a/src/main/java/com/google/firebase/FirebaseOptions.java +++ b/src/main/java/com/google/firebase/FirebaseOptions.java @@ -33,7 +33,6 @@ import com.google.firebase.internal.FirebaseThreadManagers; import com.google.firebase.internal.NonNull; import com.google.firebase.internal.Nullable; - import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -85,13 +84,15 @@ public GoogleCredentials get() { private final JsonFactory jsonFactory; private final ThreadManager threadManager; private final FirestoreOptions firestoreOptions; + private final Map processEnvironmentOverride; - private FirebaseOptions(@NonNull final FirebaseOptions.Builder builder) { + private FirebaseOptions(@NonNull final Builder builder) { this.databaseUrl = builder.databaseUrl; this.credentialsSupplier = checkNotNull( builder.credentialsSupplier, "FirebaseOptions must be initialized with setCredentials()."); this.databaseAuthVariableOverride = builder.databaseAuthVariableOverride; this.projectId = builder.projectId; + this.processEnvironmentOverride = builder.processEnvironmentOverride; if (!Strings.isNullOrEmpty(builder.storageBucket)) { checkArgument(!builder.storageBucket.startsWith("gs://"), "StorageBucket must not include 'gs://' prefix."); @@ -207,6 +208,16 @@ public int getReadTimeout() { return readTimeout; } + /** + * Return the process environment override values used for setting the env in + * {@link com.google.firebase.internal.FirebaseProcessEnvironment} + * + * @return {@link Map} of environment variables used for overriding + */ + public Map getProcessEnvironmentOverride() { + return processEnvironmentOverride; + } + @NonNull ThreadManager getThreadManager() { return threadManager; @@ -260,6 +271,7 @@ public static final class Builder { private ThreadManager threadManager; private int connectTimeout; private int readTimeout; + private Map processEnvironmentOverride; /** * Constructs an empty builder. @@ -495,6 +507,19 @@ public Builder setReadTimeout(int readTimeout) { return this; } + /** + * Sets the environment variable to override in + * {@link com.google.firebase.internal.FirebaseProcessEnvironment} + * + * @param processEnvironmentOverride {@link Map} of key, value for environment variables + * @return This Builder instance is returned so subsequent calls can be + * chained. + */ + public Builder setProcessEnvironmentOverride(Map processEnvironmentOverride) { + this.processEnvironmentOverride = processEnvironmentOverride; + return this; + } + /** * Builds the {@link FirebaseOptions} instance from the previously set options. * diff --git a/src/test/java/com/google/firebase/FirebaseOptionsTest.java b/src/test/java/com/google/firebase/FirebaseOptionsTest.java index c74215beb..03055e58d 100644 --- a/src/test/java/com/google/firebase/FirebaseOptionsTest.java +++ b/src/test/java/com/google/firebase/FirebaseOptionsTest.java @@ -33,9 +33,10 @@ import com.google.firebase.testing.ServiceAccount; import com.google.firebase.testing.TestUtils; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadFactory; - import org.junit.Test; /** @@ -76,6 +77,8 @@ public void createOptionsWithAllValuesSet() throws IOException { GsonFactory jsonFactory = new GsonFactory(); NetHttpTransport httpTransport = new NetHttpTransport(); FirestoreOptions firestoreOptions = FirestoreOptions.newBuilder().build(); + Map processEnvOverride = new HashMap<>(); + processEnvOverride.put("FIREBASE_AUTH_EMULATOR_HOST", "localhost:9092"); FirebaseOptions firebaseOptions = FirebaseOptions.builder() .setDatabaseUrl(FIREBASE_DB_URL) @@ -86,6 +89,7 @@ public void createOptionsWithAllValuesSet() throws IOException { .setHttpTransport(httpTransport) .setThreadManager(MOCK_THREAD_MANAGER) .setConnectTimeout(30000) + .setProcessEnvironmentOverride(processEnvOverride) .setReadTimeout(60000) .setFirestoreOptions(firestoreOptions) .build(); @@ -98,6 +102,8 @@ public void createOptionsWithAllValuesSet() throws IOException { assertEquals(30000, firebaseOptions.getConnectTimeout()); assertEquals(60000, firebaseOptions.getReadTimeout()); assertSame(firestoreOptions, firebaseOptions.getFirestoreOptions()); + assertEquals("localhost:9092", + firebaseOptions.getProcessEnvironmentOverride().get("FIREBASE_AUTH_EMULATOR_HOST")); GoogleCredentials credentials = firebaseOptions.getCredentials(); assertNotNull(credentials);