diff --git a/packages/cloud_functions/CHANGELOG.md b/packages/cloud_functions/CHANGELOG.md index e4661c25bd6a..57062fbbfa2c 100644 --- a/packages/cloud_functions/CHANGELOG.md +++ b/packages/cloud_functions/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.1 + +* Support for cloud functions emulators. + ## 0.4.0+3 * Update google-services Android gradle plugin to 4.3.0 in documentation and examples. @@ -93,7 +97,7 @@ [Callable functions](https://firebase.google.com/docs/functions/callable) are similar to other HTTP functions, with these additional features: - - With callables, Firebase Authentication and FCM tokens are - automatically included in requests. - - The functions.https.onCall trigger automatically deserializes - the request body and validates auth tokens. + - With callables, Firebase Authentication and FCM tokens are + automatically included in requests. + - The functions.https.onCall trigger automatically deserializes + the request body and validates auth tokens. diff --git a/packages/cloud_functions/android/src/main/java/io/flutter/plugins/firebase/cloudfunctions/CloudFunctionsPlugin.java b/packages/cloud_functions/android/src/main/java/io/flutter/plugins/firebase/cloudfunctions/CloudFunctionsPlugin.java index 81dfc98e6a95..b99ddefec324 100644 --- a/packages/cloud_functions/android/src/main/java/io/flutter/plugins/firebase/cloudfunctions/CloudFunctionsPlugin.java +++ b/packages/cloud_functions/android/src/main/java/io/flutter/plugins/firebase/cloudfunctions/CloudFunctionsPlugin.java @@ -38,12 +38,16 @@ public void onMethodCall(MethodCall call, final Result result) { String appName = call.argument("app"); FirebaseApp app = FirebaseApp.getInstance(appName); String region = call.argument("region"); + String origin = call.argument("origin"); FirebaseFunctions functions; if (region != null) { functions = FirebaseFunctions.getInstance(app, region); } else { functions = FirebaseFunctions.getInstance(app); } + if (origin != null) { + functions.useFunctionsEmulator(origin); + } HttpsCallableReference httpsCallableReference = functions.getHttpsCallable(functionName); Number timeoutMilliseconds = call.argument("timeoutMilliseconds"); if (timeoutMilliseconds != null) { diff --git a/packages/cloud_functions/ios/Classes/CloudFunctionsPlugin.m b/packages/cloud_functions/ios/Classes/CloudFunctionsPlugin.m index cdeaf53debfb..e48c0fbc73cb 100644 --- a/packages/cloud_functions/ios/Classes/CloudFunctionsPlugin.m +++ b/packages/cloud_functions/ios/Classes/CloudFunctionsPlugin.m @@ -44,6 +44,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result NSObject *parameters = call.arguments[@"parameters"]; NSString *appName = call.arguments[@"app"]; NSString *region = call.arguments[@"region"]; + NSString *origin = call.arguments[@"origin"]; NSNumber *timeoutMicroseconds = call.arguments[@"timeoutMicroseconds"]; FIRApp *app = [FIRApp appNamed:appName]; FIRFunctions *functions; @@ -52,6 +53,9 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result } else { functions = [FIRFunctions functionsForApp:app]; } + if (origin != nil && origin != (id)[NSNull null]) { + [functions useFunctionsEmulatorOrigin:origin]; + } FIRHTTPSCallable *function = [functions HTTPSCallableWithName:functionName]; if (timeoutMicroseconds != nil && timeoutMicroseconds != [NSNull null]) { [function setTimeoutInterval:(NSTimeInterval)timeoutMicroseconds.doubleValue / 1000000]; diff --git a/packages/cloud_functions/lib/src/cloud_functions.dart b/packages/cloud_functions/lib/src/cloud_functions.dart index 03c1705efa53..7d21e16f7f38 100644 --- a/packages/cloud_functions/lib/src/cloud_functions.dart +++ b/packages/cloud_functions/lib/src/cloud_functions.dart @@ -16,9 +16,10 @@ class CloudFunctionsException implements Exception { /// /// You can get an instance by calling [CloudFunctions.instance]. class CloudFunctions { - CloudFunctions({FirebaseApp app, String region}) + CloudFunctions({FirebaseApp app, String region, String origin}) : _app = app ?? FirebaseApp.instance, - _region = region; + _region = region, + _origin = origin; @visibleForTesting static const MethodChannel channel = MethodChannel('cloud_functions'); @@ -31,6 +32,8 @@ class CloudFunctions { final String _region; + String _origin; + /// Gets an instance of a Callable HTTPS trigger in Cloud Functions. /// /// Can then be executed by calling `call()` on it. @@ -39,4 +42,12 @@ class CloudFunctions { HttpsCallable getHttpsCallable({@required String functionName}) { return HttpsCallable._(this, functionName); } + + /// Changes this instance to point to a Cloud Functions emulator running locally. + /// + /// @param origin The origin of the local emulator, such as "//10.0.2.2:5005". + CloudFunctions useFunctionsEmulator({@required String origin}) { + _origin = origin; + return this; + } } diff --git a/packages/cloud_functions/lib/src/https_callable.dart b/packages/cloud_functions/lib/src/https_callable.dart index 09a8f578596f..6ae34dbf73f5 100644 --- a/packages/cloud_functions/lib/src/https_callable.dart +++ b/packages/cloud_functions/lib/src/https_callable.dart @@ -34,6 +34,7 @@ class HttpsCallable { .invokeMethod('CloudFunctions#call', { 'app': _cloudFunctions._app.name, 'region': _cloudFunctions._region, + 'origin': _cloudFunctions._origin, 'timeoutMicroseconds': timeout?.inMicroseconds, 'functionName': _functionName, 'parameters': parameters, diff --git a/packages/cloud_functions/pubspec.yaml b/packages/cloud_functions/pubspec.yaml index 20034a7acce9..d1e9bf14f4cd 100644 --- a/packages/cloud_functions/pubspec.yaml +++ b/packages/cloud_functions/pubspec.yaml @@ -1,6 +1,6 @@ name: cloud_functions description: Flutter plugin for Cloud Functions. -version: 0.4.0+3 +version: 0.4.1 author: Flutter Team homepage: https://github.com/flutter/plugins/tree/master/packages/cloud_functions @@ -23,5 +23,5 @@ dev_dependencies: test: any environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=0.2.4 <2.0.0" + sdk: '>=2.0.0-dev.28.0 <3.0.0' + flutter: '>=0.2.4 <2.0.0' diff --git a/packages/cloud_functions/test/cloud_functions_test.dart b/packages/cloud_functions/test/cloud_functions_test.dart index 10cb74ae02a6..6e58c422423f 100644 --- a/packages/cloud_functions/test/cloud_functions_test.dart +++ b/packages/cloud_functions/test/cloud_functions_test.dart @@ -38,6 +38,10 @@ void main() { await callable.call({ 'quux': 'quuz', }); + await CloudFunctions.instance + .useFunctionsEmulator(origin: 'http://localhost:5001') + .getHttpsCallable(functionName: 'bez') + .call(); expect( log, [ @@ -46,6 +50,7 @@ void main() { arguments: { 'app': '[DEFAULT]', 'region': null, + 'origin': null, 'functionName': 'baz', 'timeoutMicroseconds': null, 'parameters': null, @@ -56,11 +61,23 @@ void main() { arguments: { 'app': '1337', 'region': 'space', + 'origin': null, 'functionName': 'qux', 'timeoutMicroseconds': (const Duration(days: 300)).inMicroseconds, 'parameters': {'quux': 'quuz'}, }, ), + isMethodCall( + 'CloudFunctions#call', + arguments: { + 'app': '[DEFAULT]', + 'region': null, + 'origin': 'http://localhost:5001', + 'functionName': 'bez', + 'timeoutMicroseconds': null, + 'parameters': null, + }, + ), ], ); });