Skip to content

Commit caebf44

Browse files
authored
Functions unified emulator settings (#1688)
1 parent b2cfe18 commit caebf44

File tree

5 files changed

+103
-24
lines changed

5 files changed

+103
-24
lines changed

firebase-functions/src/androidTest/java/com/google/firebase/functions/CallTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.google.android.gms.tasks.Task;
2626
import com.google.android.gms.tasks.Tasks;
2727
import com.google.firebase.FirebaseApp;
28+
import com.google.firebase.emulators.EmulatedServiceSettings;
2829
import com.google.firebase.functions.FirebaseFunctionsException.Code;
2930
import java.util.Arrays;
3031
import java.util.HashMap;
@@ -39,6 +40,8 @@
3940
public class CallTest {
4041
private static FirebaseApp app;
4142

43+
private static final EmulatedServiceSettings NO_EMULATOR = null;
44+
4245
@BeforeClass
4346
public static void setUp() {
4447
FirebaseApp.initializeApp(InstrumentationRegistry.getContext());
@@ -90,7 +93,8 @@ public void testToken() throws InterruptedException, ExecutionException {
9093
() -> {
9194
HttpsCallableContext context = new HttpsCallableContext("token", null);
9295
return Tasks.forResult(context);
93-
});
96+
},
97+
NO_EMULATOR);
9498

9599
HttpsCallableReference function = functions.getHttpsCallable("tokenTest");
96100
Task<HttpsCallableResult> result = function.call(new HashMap<>());
@@ -110,7 +114,8 @@ public void testInstanceId() throws InterruptedException, ExecutionException {
110114
() -> {
111115
HttpsCallableContext context = new HttpsCallableContext(null, "iid");
112116
return Tasks.forResult(context);
113-
});
117+
},
118+
NO_EMULATOR);
114119

115120
HttpsCallableReference function = functions.getHttpsCallable("instanceIdTest");
116121
Task<HttpsCallableResult> result = function.call(new HashMap<>());

firebase-functions/src/androidTest/java/com/google/firebase/functions/FirebaseFunctionsTest.java

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,24 @@
1515
package com.google.firebase.functions;
1616

1717
import static org.junit.Assert.assertEquals;
18-
import static org.mockito.Mockito.mock;
19-
import static org.mockito.Mockito.when;
2018

21-
import androidx.test.InstrumentationRegistry;
19+
import androidx.test.platform.app.InstrumentationRegistry;
2220
import androidx.test.runner.AndroidJUnit4;
2321
import com.google.firebase.FirebaseApp;
22+
import com.google.firebase.FirebaseOptions;
23+
import com.google.firebase.emulators.EmulatedServiceSettings;
24+
import com.google.firebase.emulators.EmulatorSettings;
2425
import java.net.URL;
25-
import org.junit.Before;
2626
import org.junit.Test;
2727
import org.junit.runner.RunWith;
2828

2929
@RunWith(AndroidJUnit4.class)
3030
public class FirebaseFunctionsTest {
31-
private final FirebaseApp app = mock(FirebaseApp.class);
32-
private final ContextProvider provider = mock(ContextProvider.class);
33-
34-
@Before
35-
public void setUp() {
36-
when(app.get(FunctionsMultiResourceComponent.class))
37-
.thenReturn(
38-
new FunctionsMultiResourceComponent(
39-
InstrumentationRegistry.getTargetContext(), provider, "my-project"));
40-
}
4131

4232
@Test
4333
public void testGetUrl() {
34+
FirebaseApp app = getApp("testGetUrl");
35+
4436
FirebaseFunctions functions = FirebaseFunctions.getInstance(app, "my-region");
4537
URL url = functions.getURL("my-endpoint");
4638
assertEquals("https://my-region-my-project.cloudfunctions.net/my-endpoint", url.toString());
@@ -49,4 +41,52 @@ public void testGetUrl() {
4941
url = functions.getURL("my-endpoint");
5042
assertEquals("https://us-central1-my-project.cloudfunctions.net/my-endpoint", url.toString());
5143
}
44+
45+
@Test
46+
public void testGetUrl_withEmulator() {
47+
FirebaseApp app = getApp("testGetUrl_withEmulator");
48+
49+
app.enableEmulators(
50+
new EmulatorSettings.Builder()
51+
.addEmulatedService(
52+
FirebaseFunctions.EMULATOR, new EmulatedServiceSettings("10.0.2.2", 5001))
53+
.build());
54+
55+
URL withRegion = FirebaseFunctions.getInstance(app, "my-region").getURL("my-endpoint");
56+
assertEquals("http://10.0.2.2:5001/my-project/my-region/my-endpoint", withRegion.toString());
57+
58+
URL withoutRegion = FirebaseFunctions.getInstance(app).getURL("my-endpoint");
59+
assertEquals(
60+
"http://10.0.2.2:5001/my-project/us-central1/my-endpoint", withoutRegion.toString());
61+
}
62+
63+
@Test
64+
public void testGetUrl_withEmulator_matchesOldImpl() {
65+
FirebaseApp app = getApp("testGetUrl_withEmulator_matchesOldImpl");
66+
67+
app.enableEmulators(
68+
new EmulatorSettings.Builder()
69+
.addEmulatedService(
70+
FirebaseFunctions.EMULATOR, new EmulatedServiceSettings("10.0.2.2", 5001))
71+
.build());
72+
73+
FirebaseFunctions functions = FirebaseFunctions.getInstance(app);
74+
URL newImplUrl = functions.getURL("my-endpoint");
75+
76+
functions.useFunctionsEmulator("http://10.0.2.2:5001");
77+
URL oldImplUrl = functions.getURL("my-endpoint");
78+
79+
assertEquals(newImplUrl.toString(), oldImplUrl.toString());
80+
}
81+
82+
private FirebaseApp getApp(String name) {
83+
return FirebaseApp.initializeApp(
84+
InstrumentationRegistry.getInstrumentation().getTargetContext(),
85+
new FirebaseOptions.Builder()
86+
.setProjectId("my-project")
87+
.setApplicationId("appid")
88+
.setApiKey("apikey")
89+
.build(),
90+
name);
91+
}
5292
}

firebase-functions/src/main/java/com/google/firebase/functions/FirebaseFunctions.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import com.google.android.gms.tasks.TaskCompletionSource;
2828
import com.google.android.gms.tasks.Tasks;
2929
import com.google.firebase.FirebaseApp;
30+
import com.google.firebase.emulators.EmulatedServiceSettings;
31+
import com.google.firebase.emulators.FirebaseEmulator;
3032
import com.google.firebase.functions.FirebaseFunctionsException.Code;
3133
import java.io.IOException;
3234
import java.io.InterruptedIOException;
@@ -47,6 +49,17 @@
4749
/** FirebaseFunctions lets you call Cloud Functions for Firebase. */
4850
public class FirebaseFunctions {
4951

52+
/**
53+
* Emulator identifier, see {@link
54+
* com.google.firebase.emulators.EmulatorSettings.Builder#addEmulatedService(FirebaseEmulator,
55+
* EmulatedServiceSettings)}
56+
*
57+
* <p>TODO(samstern): Un-hide this once Firestore, Database, and Functions are implemented
58+
*
59+
* @hide
60+
*/
61+
public static final FirebaseEmulator EMULATOR = FirebaseEmulator.forName("functions");
62+
5063
/** A task that will be resolved once ProviderInstaller has installed what it needs to. */
5164
private static final TaskCompletionSource<Void> providerInstalled = new TaskCompletionSource<>();
5265

@@ -75,13 +88,26 @@ public class FirebaseFunctions {
7588
private String urlFormat = "https://%1$s-%2$s.cloudfunctions.net/%3$s";
7689

7790
FirebaseFunctions(
78-
Context context, String projectId, String region, ContextProvider contextProvider) {
91+
Context context,
92+
String projectId,
93+
String region,
94+
ContextProvider contextProvider,
95+
@Nullable EmulatedServiceSettings emulatorSettings) {
7996
this.client = new OkHttpClient();
8097
this.serializer = new Serializer();
8198
this.contextProvider = Preconditions.checkNotNull(contextProvider);
8299
this.projectId = Preconditions.checkNotNull(projectId);
83100
this.region = Preconditions.checkNotNull(region);
84101

102+
if (emulatorSettings != null) {
103+
urlFormat =
104+
"http://"
105+
+ emulatorSettings.getHost()
106+
+ ":"
107+
+ emulatorSettings.getPort()
108+
+ "/%2$s/%1$s/%3$s";
109+
}
110+
85111
maybeInstallProviders(context);
86112
}
87113

firebase-functions/src/main/java/com/google/firebase/functions/FunctionsMultiResourceComponent.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
import android.content.Context;
1818
import androidx.annotation.GuardedBy;
19+
import com.google.firebase.FirebaseApp;
20+
import com.google.firebase.emulators.EmulatedServiceSettings;
1921
import java.util.HashMap;
2022
import java.util.Map;
2123

@@ -31,19 +33,25 @@ class FunctionsMultiResourceComponent {
3133

3234
private final Context applicationContext;
3335
private final ContextProvider contextProvider;
34-
private final String projectId;
36+
private final FirebaseApp app;
3537

3638
FunctionsMultiResourceComponent(
37-
Context applicationContext, ContextProvider contextProvider, String projectId) {
39+
Context applicationContext, ContextProvider contextProvider, FirebaseApp app) {
3840
this.applicationContext = applicationContext;
3941
this.contextProvider = contextProvider;
40-
this.projectId = projectId;
42+
this.app = app;
4143
}
4244

4345
synchronized FirebaseFunctions get(String region) {
4446
FirebaseFunctions functions = instances.get(region);
47+
String projectId = app.getOptions().getProjectId();
48+
EmulatedServiceSettings emulatorSettings =
49+
app.getEmulatorSettings().getServiceSettings(FirebaseFunctions.EMULATOR);
50+
4551
if (functions == null) {
46-
functions = new FirebaseFunctions(applicationContext, projectId, region, contextProvider);
52+
functions =
53+
new FirebaseFunctions(
54+
applicationContext, projectId, region, contextProvider, emulatorSettings);
4755
instances.put(region, functions);
4856
}
4957
return functions;

firebase-functions/src/main/java/com/google/firebase/functions/FunctionsRegistrar.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import android.content.Context;
1818
import androidx.annotation.Keep;
19-
import com.google.firebase.FirebaseOptions;
19+
import com.google.firebase.FirebaseApp;
2020
import com.google.firebase.auth.internal.InternalAuthProvider;
2121
import com.google.firebase.components.Component;
2222
import com.google.firebase.components.ComponentRegistrar;
@@ -48,13 +48,13 @@ public List<Component<?>> getComponents() {
4848
Component.builder(FunctionsMultiResourceComponent.class)
4949
.add(Dependency.required(Context.class))
5050
.add(Dependency.required(ContextProvider.class))
51-
.add(Dependency.required(FirebaseOptions.class))
51+
.add(Dependency.required(FirebaseApp.class))
5252
.factory(
5353
c ->
5454
new FunctionsMultiResourceComponent(
5555
c.get(Context.class),
5656
c.get(ContextProvider.class),
57-
c.get(FirebaseOptions.class).getProjectId()))
57+
c.get(FirebaseApp.class)))
5858
.build(),
5959
LibraryVersionComponent.create("fire-fn", BuildConfig.VERSION_NAME));
6060
}

0 commit comments

Comments
 (0)