Skip to content

Commit 3f369c8

Browse files
fix(functions): return correct type on native (#5709)
1 parent 03671fa commit 3f369c8

File tree

4 files changed

+59
-34
lines changed

4 files changed

+59
-34
lines changed

.editorconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ end_of_line = lf
88
charset = utf-8
99
trim_trailing_whitespace = true
1010
insert_final_newline = true
11+
quote_type = single

.github/workflows/scripts/functions/src/index.ts

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,42 @@
1-
import * as assert from "assert";
1+
import * as assert from 'assert';
22
import * as functions from 'firebase-functions';
33

44
// For example app.
55
// noinspection JSUnusedGlobalSymbols
66
export const listFruit = functions.https.onCall(() => {
7-
return [
8-
"Apple",
9-
"Banana",
10-
"Cherry",
11-
"Date",
12-
"Fig",
13-
"Grapes"
14-
];
7+
return ['Apple', 'Banana', 'Cherry', 'Date', 'Fig', 'Grapes'];
158
});
169

17-
1810
// For e2e testing a custom region.
1911
// noinspection JSUnusedGlobalSymbols
2012
export const testFunctionCustomRegion = functions
2113
.region('europe-west1')
2214
.https.onCall(() => 'europe-west1');
2315

2416
// For e2e testing timeouts.
25-
export const testFunctionTimeout = functions
26-
.https.onCall(data => {
27-
console.log(JSON.stringify({data}));
28-
return new Promise((resolve, reject) => {
29-
if (data && data.testTimeout) {
30-
setTimeout(() => resolve({timeLimit: 'exceeded'}), parseInt(data.testTimeout, 10));
31-
} else {
32-
reject(new functions.https.HttpsError(
17+
export const testFunctionTimeout = functions.https.onCall((data) => {
18+
console.log(JSON.stringify({ data }));
19+
return new Promise((resolve, reject) => {
20+
if (data && data.testTimeout) {
21+
setTimeout(
22+
() => resolve({ timeLimit: 'exceeded' }),
23+
parseInt(data.testTimeout, 10)
24+
);
25+
} else {
26+
reject(
27+
new functions.https.HttpsError(
3328
'invalid-argument',
3429
'testTimeout must be provided.'
35-
));
36-
}
37-
});
30+
)
31+
);
32+
}
3833
});
34+
});
3935

4036
// For e2e testing errors & return values.
4137
// noinspection JSUnusedGlobalSymbols
42-
export const testFunctionDefaultRegion = functions.https.onCall(data => {
43-
console.log(JSON.stringify({data}));
38+
export const testFunctionDefaultRegion = functions.https.onCall((data) => {
39+
console.log(JSON.stringify({ data }));
4440
if (typeof data === 'undefined') {
4541
return 'undefined';
4642
}
@@ -66,12 +62,12 @@ export const testFunctionDefaultRegion = functions.https.onCall(data => {
6662
}
6763

6864
const sampleData: {
69-
[key: string]: any
65+
[key: string]: any;
7066
} = {
7167
number: 1234,
7268
string: 'acde',
7369
boolean: true,
74-
'null': null,
70+
null: null,
7571
map: {
7672
number: 1234,
7773
string: 'acde',
@@ -85,8 +81,8 @@ export const testFunctionDefaultRegion = functions.https.onCall(data => {
8581
booleanTrue: true,
8682
booleanFalse: false,
8783
null: null,
88-
'list': ['1', 2, true, false],
89-
'map': {
84+
list: ['1', 2, true, false],
85+
map: {
9086
number: 123,
9187
string: 'foo',
9288
booleanTrue: true,
@@ -95,7 +91,10 @@ export const testFunctionDefaultRegion = functions.https.onCall(data => {
9591
},
9692
},
9793
deepList: [
98-
'1', 2, true, false,
94+
'1',
95+
2,
96+
true,
97+
false,
9998
['1', 2, true, false],
10099
{
101100
number: 123,
@@ -107,10 +106,14 @@ export const testFunctionDefaultRegion = functions.https.onCall(data => {
107106
],
108107
};
109108

110-
const {type, asError, inputData}: {
111-
type: string,
112-
asError?: boolean,
113-
inputData?: any,
109+
const {
110+
type,
111+
asError,
112+
inputData,
113+
}: {
114+
type: string;
115+
asError?: boolean;
116+
inputData?: any;
114117
} = data;
115118
if (!Object.hasOwnProperty.call(sampleData, type)) {
116119
throw new functions.https.HttpsError(
@@ -144,3 +147,6 @@ export const testFunctionDefaultRegion = functions.https.onCall(data => {
144147
return outputData;
145148
});
146149

150+
export const testMapConvertType = functions.https.onCall((data) => ({
151+
foo: 'bar',
152+
}));

packages/cloud_functions/cloud_functions/example/test_driver/cloud_functions_e2e.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import 'sample.dart' as data;
1616
String kTestFunctionDefaultRegion = 'testFunctionDefaultRegion';
1717
String kTestFunctionCustomRegion = 'testFunctionCustomRegion';
1818
String kTestFunctionTimeout = 'testFunctionTimeout';
19+
String kTestMapConvertType = 'testMapConvertType';
1920

2021
void testsMain() {
2122
HttpsCallable callable;
@@ -82,6 +83,17 @@ void testsMain() {
8283
});
8384
expect(result.data, equals(data.deepList));
8485
});
86+
87+
test(
88+
'[HttpsCallableResult.data] should return Map<String, dynamic> type for returned objects',
89+
() async {
90+
HttpsCallable callable =
91+
FirebaseFunctions.instance.httpsCallable(kTestMapConvertType);
92+
93+
var result = await callable();
94+
95+
expect(result.data, isA<Map<String, dynamic>>());
96+
});
8597
});
8698

8799
group('FirebaseFunctionsException', () {

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ class MethodChannelHttpsCallable extends HttpsCallablePlatform {
1717
: super(functions, origin, name, options);
1818

1919
@override
20-
Future<dynamic> call([dynamic parameters]) {
21-
return MethodChannelFirebaseFunctions.channel
20+
Future<dynamic> call([Object? parameters]) async {
21+
Object? result = await MethodChannelFirebaseFunctions.channel
2222
.invokeMethod('FirebaseFunctions#call', <String, dynamic>{
2323
'appName': functions.app!.name,
2424
'functionName': name,
@@ -27,5 +27,11 @@ class MethodChannelHttpsCallable extends HttpsCallablePlatform {
2727
'timeout': options.timeout.inMilliseconds,
2828
'parameters': parameters,
2929
}).catchError(catchPlatformException);
30+
31+
if (result is Map) {
32+
return Map<String, dynamic>.from(result);
33+
} else {
34+
return result;
35+
}
3036
}
3137
}

0 commit comments

Comments
 (0)