Skip to content

Commit 9fce7f2

Browse files
feat(functions): pass limitedUseAppCheckToken option to Cloud Function (#11402)
1 parent b569f16 commit 9fce7f2

File tree

10 files changed

+58
-15
lines changed

10 files changed

+58
-15
lines changed

packages/cloud_functions/cloud_functions/android/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ buildscript {
88
}
99

1010
dependencies {
11-
classpath 'com.android.tools.build:gradle:3.5.4'
11+
classpath 'com.android.tools.build:gradle:8.0.1'
1212
}
1313
}
1414

@@ -39,7 +39,7 @@ android {
3939
if (project.android.hasProperty("namespace")) {
4040
namespace 'io.flutter.plugins.firebase.functions'
4141
}
42-
42+
4343
compileSdkVersion 31
4444
compileOptions {
4545
sourceCompatibility JavaVersion.VERSION_1_8

packages/cloud_functions/cloud_functions/android/src/main/java/io/flutter/plugins/firebase/functions/FlutterFirebaseFunctionsPlugin.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.google.firebase.FirebaseApp;
1414
import com.google.firebase.functions.FirebaseFunctions;
1515
import com.google.firebase.functions.FirebaseFunctionsException;
16+
import com.google.firebase.functions.HttpsCallableOptions;
1617
import com.google.firebase.functions.HttpsCallableReference;
1718
import com.google.firebase.functions.HttpsCallableResult;
1819
import io.flutter.embedding.engine.plugins.FlutterPlugin;
@@ -74,6 +75,8 @@ private Task<Object> httpsFunctionCall(Map<String, Object> arguments) {
7475
String functionUri = (String) arguments.get("functionUri");
7576
String origin = (String) arguments.get("origin");
7677
Integer timeout = (Integer) arguments.get("timeout");
78+
boolean limitedUseAppCheckToken =
79+
(boolean) Objects.requireNonNull(arguments.get("limitedUseAppCheckToken"));
7780
Object parameters = arguments.get("parameters");
7881

7982
if (origin != null) {
@@ -82,12 +85,16 @@ private Task<Object> httpsFunctionCall(Map<String, Object> arguments) {
8285
}
8386

8487
HttpsCallableReference httpsCallableReference;
88+
HttpsCallableOptions options =
89+
new HttpsCallableOptions.Builder()
90+
.setLimitedUseAppCheckTokens(limitedUseAppCheckToken)
91+
.build();
8592

8693
if (functionName != null) {
87-
httpsCallableReference = firebaseFunctions.getHttpsCallable(functionName);
94+
httpsCallableReference = firebaseFunctions.getHttpsCallable(functionName, options);
8895
} else if (functionUri != null) {
8996
httpsCallableReference =
90-
firebaseFunctions.getHttpsCallableFromUrl(new URL(functionUri));
97+
firebaseFunctions.getHttpsCallableFromUrl(new URL(functionUri), options);
9198
} else {
9299
throw new IllegalArgumentException("Either functionName or functionUri must be set");
93100
}

packages/cloud_functions/cloud_functions/example/android/app/build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,10 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
2626

2727
android {
2828
namespace 'io.flutter.plugins.firebase.functions.example'
29-
compileSdkVersion 33
29+
compileSdk 33
3030

31-
lintOptions {
32-
disable 'InvalidPackage'
33-
}
3431

35-
defaultConfig {
32+
defaultConfig {
3633
applicationId "io.flutter.plugins.firebase.functions.example"
3734
minSdkVersion 16
3835
targetSdkVersion 33
@@ -48,6 +45,9 @@ android {
4845
signingConfig signingConfigs.debug
4946
}
5047
}
48+
lint {
49+
disable 'InvalidPackage'
50+
}
5151
}
5252

5353
flutter {

packages/cloud_functions/cloud_functions/ios/Classes/FLTFirebaseFunctionsPlugin.m

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ - (void)httpsFunctionCall:(id)arguments withMethodCallResult:(FLTFirebaseMethodC
8686
NSString *region = arguments[@"region"];
8787
NSNumber *timeout = arguments[@"timeout"];
8888
NSObject *parameters = arguments[@"parameters"];
89+
NSNumber *limitedUseAppCheckToken = arguments[@"limitedUseAppCheckToken"];
8990

9091
FIRApp *app = [FLTFirebasePlugin firebaseAppNamed:appName];
9192
FIRFunctions *functions = [FIRFunctions functionsForApp:app region:region];
@@ -94,12 +95,15 @@ - (void)httpsFunctionCall:(id)arguments withMethodCallResult:(FLTFirebaseMethodC
9495
[functions useEmulatorWithHost:[url host] port:[[url port] intValue]];
9596
}
9697

98+
FIRHTTPSCallableOptions *options = [[FIRHTTPSCallableOptions alloc]
99+
initWithRequireLimitedUseAppCheckTokens:[limitedUseAppCheckToken boolValue]];
100+
97101
FIRHTTPSCallable *function;
98102

99103
if (![functionName isEqual:[NSNull null]]) {
100-
function = [functions HTTPSCallableWithName:functionName];
104+
function = [functions HTTPSCallableWithName:functionName options:options];
101105
} else if (![functionUri isEqual:[NSNull null]]) {
102-
function = [functions HTTPSCallableWithURL:[NSURL URLWithString:functionUri]];
106+
function = [functions HTTPSCallableWithURL:[NSURL URLWithString:functionUri] options:options];
103107
} else {
104108
result.error(@"IllegalArgumentException", @"Either functionName or functionUri must be set",
105109
nil, nil);

packages/cloud_functions/cloud_functions_platform_interface/lib/src/https_callable_options.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55

66
/// Interface representing an HttpsCallable instance's options,
77
class HttpsCallableOptions {
8-
/// Constructs a new [HttpsCallableOptions] instance with given timeout.
8+
/// Constructs a new [HttpsCallableOptions] instance with given `timeout` & `limitedUseAppCheckToken`
99
/// Defaults [timeout] to 60 seconds.
10-
HttpsCallableOptions({this.timeout = const Duration(seconds: 60)});
10+
/// Defaults [limitedUseAppCheckToken] to `false`
11+
HttpsCallableOptions(
12+
{this.timeout = const Duration(seconds: 60),
13+
this.limitedUseAppCheckToken = false});
1114

1215
/// Returns the timeout for this instance
1316
Duration timeout;
17+
18+
/// Sets whether or not to use limited-use App Check tokens when invoking the associated function.
19+
bool limitedUseAppCheckToken;
1420
}

packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_https_callable.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class MethodChannelHttpsCallable extends HttpsCallablePlatform {
2828
'region': functions.region,
2929
'timeout': options.timeout.inMilliseconds,
3030
'parameters': parameters,
31+
'limitedUseAppCheckToken': options.limitedUseAppCheckToken,
3132
});
3233

3334
if (result is Map) {

packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/method_channel_https_callable_test.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ void main() {
8989
expect(httpsCallable!.options, isInstanceOf<HttpsCallableOptions>());
9090
expect(httpsCallable!.options.timeout, isInstanceOf<Duration>());
9191
expect(httpsCallable!.options.timeout.inMinutes, 1);
92+
expect(httpsCallable!.options.limitedUseAppCheckToken, false);
9293
});
9394
});
9495

@@ -119,6 +120,7 @@ void main() {
119120
'region': functions!.region,
120121
'timeout': httpsCallable!.options.timeout.inMilliseconds,
121122
'parameters': kParameters,
123+
'limitedUseAppCheckToken': false,
122124
},
123125
),
124126
]);
@@ -149,6 +151,7 @@ void main() {
149151
'region': functions!.region,
150152
'timeout': httpsCallable!.options.timeout.inMilliseconds,
151153
'parameters': kParameters,
154+
'limitedUseAppCheckToken': false,
152155
},
153156
),
154157
]);
@@ -169,6 +172,7 @@ void main() {
169172
'region': functions!.region,
170173
'timeout': httpsCallable!.options.timeout.inMilliseconds,
171174
'parameters': null,
175+
'limitedUseAppCheckToken': false,
172176
},
173177
),
174178
]);
@@ -189,6 +193,7 @@ void main() {
189193
'region': functions!.region,
190194
'timeout': httpsCallable!.options.timeout.inMilliseconds,
191195
'parameters': null,
196+
'limitedUseAppCheckToken': false,
192197
},
193198
),
194199
]);

packages/cloud_functions/cloud_functions_web/lib/https_callable_web.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ class HttpsCallableWeb extends HttpsCallablePlatform {
3030

3131
functions_interop.HttpsCallableOptions callableOptions =
3232
functions_interop.HttpsCallableOptions(
33-
timeout: options.timeout.inMilliseconds);
33+
timeout: options.timeout.inMilliseconds,
34+
limitedUseAppCheckTokens: options.limitedUseAppCheckToken,
35+
);
3436

3537
late functions_interop.HttpsCallable callable;
3638

packages/cloud_functions/cloud_functions_web/lib/interop/functions_interop.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@ abstract class FunctionsJsImpl {
4444
@JS('HttpsCallableOptions')
4545
@anonymous
4646
abstract class HttpsCallableOptions {
47-
external factory HttpsCallableOptions({int? timeout});
47+
external factory HttpsCallableOptions(
48+
{int? timeout, bool? limitedUseAppCheckTokens});
4849
external int get timeout;
4950
external set timeout(int t);
51+
external bool get limitedUseAppCheckTokens;
52+
external set limitedUseAppCheckTokens(bool t);
5053
}
5154

5255
/// An HttpsCallableResult wraps a single result from a function call.

tests/integration_test/cloud_functions/cloud_functions_e2e_test.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,21 @@ void main() {
227227
// https://github.com/firebase/flutterfire/issues/9652
228228
skip: defaultTargetPlatform == TargetPlatform.android,
229229
);
230+
231+
test(
232+
'allow passing of `limitedUseAppCheckToken` as option',
233+
() async {
234+
final instance = FirebaseFunctions.instance;
235+
instance.useFunctionsEmulator('localhost', 5001);
236+
final timeoutCallable = FirebaseFunctions.instance.httpsCallable(
237+
kTestFunctionDefaultRegion,
238+
options: HttpsCallableOptions(timeout: const Duration(seconds: 3), limitedUseAppCheckToken: true),
239+
);
240+
241+
HttpsCallableResult results = await timeoutCallable(null);
242+
expect(results.data, equals('null'));
243+
},
244+
);
230245
});
231246
});
232247
}

0 commit comments

Comments
 (0)