Skip to content

Commit 4f3ffc5

Browse files
authored
Add custom domain support to callable functions (#2100)
1 parent fd76164 commit 4f3ffc5

File tree

5 files changed

+66
-22
lines changed

5 files changed

+66
-22
lines changed

firebase-functions/ktx/api.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package com.google.firebase.functions.ktx {
33

44
public final class FunctionsKt {
55
ctor public FunctionsKt();
6-
method @NonNull public static com.google.firebase.functions.FirebaseFunctions functions(@NonNull com.google.firebase.ktx.Firebase, @NonNull String region);
6+
method @NonNull public static com.google.firebase.functions.FirebaseFunctions functions(@NonNull com.google.firebase.ktx.Firebase, @NonNull String regionOrCustomDomain);
77
method @NonNull public static com.google.firebase.functions.FirebaseFunctions functions(@NonNull com.google.firebase.ktx.Firebase, @NonNull com.google.firebase.FirebaseApp app);
8-
method @NonNull public static com.google.firebase.functions.FirebaseFunctions functions(@NonNull com.google.firebase.ktx.Firebase, @NonNull com.google.firebase.FirebaseApp app, @NonNull String region);
8+
method @NonNull public static com.google.firebase.functions.FirebaseFunctions functions(@NonNull com.google.firebase.ktx.Firebase, @NonNull com.google.firebase.FirebaseApp app, @NonNull String regionOrCustomDomain);
99
method @NonNull public static com.google.firebase.functions.FirebaseFunctions getFunctions(@NonNull com.google.firebase.ktx.Firebase);
1010
}
1111

firebase-functions/ktx/src/main/kotlin/com/google/firebase/functions/ktx/Functions.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ import com.google.firebase.platforminfo.LibraryVersionComponent
2626
val Firebase.functions: FirebaseFunctions
2727
get() = FirebaseFunctions.getInstance()
2828

29-
/** Returns the [FirebaseFunctions] instance of a given [region]. */
30-
fun Firebase.functions(region: String): FirebaseFunctions = FirebaseFunctions.getInstance(region)
29+
/** Returns the [FirebaseFunctions] instance of a given [regionOrCustomDomain]. */
30+
fun Firebase.functions(regionOrCustomDomain: String): FirebaseFunctions =
31+
FirebaseFunctions.getInstance(regionOrCustomDomain)
3132

3233
/** Returns the [FirebaseFunctions] instance of a given [FirebaseApp]. */
3334
fun Firebase.functions(app: FirebaseApp): FirebaseFunctions = FirebaseFunctions.getInstance(app)
3435

35-
/** Returns the [FirebaseFunctions] instance of a given [FirebaseApp] and [region]. */
36-
fun Firebase.functions(app: FirebaseApp, region: String): FirebaseFunctions =
37-
FirebaseFunctions.getInstance(app, region)
36+
/** Returns the [FirebaseFunctions] instance of a given [FirebaseApp] and [regionOrCustomDomain]. */
37+
fun Firebase.functions(app: FirebaseApp, regionOrCustomDomain: String): FirebaseFunctions =
38+
FirebaseFunctions.getInstance(app, regionOrCustomDomain)
3839

3940
internal const val LIBRARY_NAME: String = "fire-fun-ktx"
4041

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ public void testGetUrl() {
3838
functions = FirebaseFunctions.getInstance(app);
3939
url = functions.getURL("my-endpoint");
4040
assertEquals("https://us-central1-my-project.cloudfunctions.net/my-endpoint", url.toString());
41+
42+
functions = FirebaseFunctions.getInstance(app, "https://mydomain.com");
43+
url = functions.getURL("my-endpoint");
44+
assertEquals("https://mydomain.com/my-endpoint", url.toString());
45+
46+
functions = FirebaseFunctions.getInstance(app, "https://mydomain.com/foo");
47+
url = functions.getURL("my-endpoint");
48+
assertEquals("https://mydomain.com/foo/my-endpoint", url.toString());
4149
}
4250

4351
@Test
@@ -57,6 +65,14 @@ public void testGetUrl_withEmulator() {
5765

5866
URL withRegion = functionsWithRegion.getURL("my-endpoint");
5967
assertEquals("http://10.0.2.2:5001/my-project/my-region/my-endpoint", withRegion.toString());
68+
69+
FirebaseFunctions functionsWithCustomDomain =
70+
FirebaseFunctions.getInstance(app, "https://mydomain.com");
71+
functionsWithCustomDomain.useEmulator("10.0.2.2", 5001);
72+
73+
URL withCustomDOmain = functionsWithCustomDomain.getURL("my-endpoint");
74+
assertEquals(
75+
"http://10.0.2.2:5001/my-project/us-central1/my-endpoint", withCustomDOmain.toString());
6076
}
6177

6278
@Test

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

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ public class FirebaseFunctions {
7575
// The region to use for all function references.
7676
private final String region;
7777

78+
// A custom domain for the http trigger, such as "https://mydomain.com"
79+
@Nullable private final String customDomain;
80+
7881
// The format to use for constructing urls from region, projectId, and name.
7982
private String urlFormat = "https://%1$s-%2$s.cloudfunctions.net/%3$s";
8083

@@ -85,14 +88,29 @@ public class FirebaseFunctions {
8588
FirebaseApp app,
8689
Context context,
8790
String projectId,
88-
String region,
91+
String regionOrCustomDomain,
8992
ContextProvider contextProvider) {
9093
this.app = app;
9194
this.client = new OkHttpClient();
9295
this.serializer = new Serializer();
9396
this.contextProvider = Preconditions.checkNotNull(contextProvider);
9497
this.projectId = Preconditions.checkNotNull(projectId);
95-
this.region = Preconditions.checkNotNull(region);
98+
99+
boolean isRegion;
100+
try {
101+
new URL(regionOrCustomDomain);
102+
isRegion = false;
103+
} catch (MalformedURLException malformedURLException) {
104+
isRegion = true;
105+
}
106+
107+
if (isRegion) {
108+
this.region = regionOrCustomDomain;
109+
this.customDomain = null;
110+
} else {
111+
this.region = "us-central1";
112+
this.customDomain = regionOrCustomDomain;
113+
}
96114

97115
maybeInstallProviders(context);
98116
}
@@ -135,20 +153,22 @@ public void onProviderInstallFailed(int i, android.content.Intent intent) {
135153
}
136154

137155
/**
138-
* Creates a Cloud Functions client with the given app and region.
156+
* Creates a Cloud Functions client with the given app and region or custom domain.
139157
*
140158
* @param app The app for the Firebase project.
141-
* @param region The region for the HTTPS trigger, such as "us-central1".
159+
* @param regionOrCustomDomain The region or custom domain for the HTTPS trigger, such as
160+
* "us-central1" or "https://mydomain.com".
142161
*/
143162
@NonNull
144-
public static FirebaseFunctions getInstance(@NonNull FirebaseApp app, @NonNull String region) {
163+
public static FirebaseFunctions getInstance(
164+
@NonNull FirebaseApp app, @NonNull String regionOrCustomDomain) {
145165
Preconditions.checkNotNull(app, "You must call FirebaseApp.initializeApp first.");
146-
Preconditions.checkNotNull(region);
166+
Preconditions.checkNotNull(regionOrCustomDomain);
147167

148168
FunctionsMultiResourceComponent component = app.get(FunctionsMultiResourceComponent.class);
149169
Preconditions.checkNotNull(component, "Functions component does not exist.");
150170

151-
return component.get(region);
171+
return component.get(regionOrCustomDomain);
152172
}
153173

154174
/**
@@ -162,13 +182,14 @@ public static FirebaseFunctions getInstance(@NonNull FirebaseApp app) {
162182
}
163183

164184
/**
165-
* Creates a Cloud Functions client with the default app and given region.
185+
* Creates a Cloud Functions client with the default app and given region or custom domain.
166186
*
167-
* @param region The region for the HTTPS trigger, such as "us-central1".
187+
* @param regionOrCustomDomain The regionOrCustomDomain for the HTTPS trigger, such as
188+
* "us-central1" or "https://mydomain.com".
168189
*/
169190
@NonNull
170-
public static FirebaseFunctions getInstance(@NonNull String region) {
171-
return getInstance(FirebaseApp.getInstance(), region);
191+
public static FirebaseFunctions getInstance(@NonNull String regionOrCustomDomain) {
192+
return getInstance(FirebaseApp.getInstance(), regionOrCustomDomain);
172193
}
173194

174195
/** Creates a Cloud Functions client with the default app. */
@@ -202,6 +223,11 @@ URL getURL(String function) {
202223
}
203224

204225
String str = String.format(urlFormat, region, projectId, function);
226+
227+
if (customDomain != null && emulatorSettings == null) {
228+
str = customDomain + "/" + function;
229+
}
230+
205231
try {
206232
return new URL(str);
207233
} catch (MalformedURLException mfe) {

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,15 @@ class FunctionsMultiResourceComponent {
4141
this.app = app;
4242
}
4343

44-
synchronized FirebaseFunctions get(String region) {
45-
FirebaseFunctions functions = instances.get(region);
44+
synchronized FirebaseFunctions get(String regionOrCustomDomain) {
45+
FirebaseFunctions functions = instances.get(regionOrCustomDomain);
4646
String projectId = app.getOptions().getProjectId();
4747

4848
if (functions == null) {
4949
functions =
50-
new FirebaseFunctions(app, applicationContext, projectId, region, contextProvider);
51-
instances.put(region, functions);
50+
new FirebaseFunctions(
51+
app, applicationContext, projectId, regionOrCustomDomain, contextProvider);
52+
instances.put(regionOrCustomDomain, functions);
5253
}
5354
return functions;
5455
}

0 commit comments

Comments
 (0)