Skip to content

Commit 8288b81

Browse files
fix(cloud_functions): Allow raw data arguments to be passed as data to Cloud Function for Android & iOS. (#7994)
Co-authored-by: Mike Diarmid <[email protected]>
1 parent 85739b4 commit 8288b81

File tree

7 files changed

+136
-49
lines changed

7 files changed

+136
-49
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ export const testFunctionDefaultRegion = functions.https.onCall((data) => {
6161
return 'array';
6262
}
6363

64+
if(data.type === 'rawData') {
65+
return data;
66+
}
67+
6468
const sampleData: {
6569
[key: string]: any;
6670
} = {

packages/cloud_functions/cloud_functions/example/lib/firebase_config.dart

Lines changed: 0 additions & 46 deletions
This file was deleted.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// File generated by FlutterFire CLI.
2+
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
3+
import 'package:flutter/foundation.dart'
4+
show defaultTargetPlatform, kIsWeb, TargetPlatform;
5+
6+
class DefaultFirebaseOptions {
7+
static FirebaseOptions get currentPlatform {
8+
if (kIsWeb) {
9+
return web;
10+
}
11+
// ignore: missing_enum_constant_in_switch
12+
switch (defaultTargetPlatform) {
13+
case TargetPlatform.android:
14+
return android;
15+
case TargetPlatform.iOS:
16+
return ios;
17+
case TargetPlatform.macOS:
18+
return macos;
19+
}
20+
21+
throw UnsupportedError(
22+
'DefaultFirebaseOptions are not supported for this platform.',
23+
);
24+
}
25+
26+
static const FirebaseOptions web = FirebaseOptions(
27+
apiKey: 'AIzaSyB7wZb2tO1-Fs6GbDADUSTs2Qs3w08Hovw',
28+
appId: '1:406099696497:web:d15569c1e161ad253574d0',
29+
messagingSenderId: '406099696497',
30+
projectId: 'flutterfire-e2e-tests',
31+
authDomain: 'flutterfire-e2e-tests.firebaseapp.com',
32+
databaseURL:
33+
'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
34+
storageBucket: 'flutterfire-e2e-tests.appspot.com',
35+
measurementId: 'G-Q5JXJGXDS9',
36+
);
37+
38+
static const FirebaseOptions android = FirebaseOptions(
39+
apiKey: 'AIzaSyCdRjCVZlhrq72RuEklEyyxYlBRCYhI2Sw',
40+
appId: '1:406099696497:android:7ca3394493cc601a3574d0',
41+
messagingSenderId: '406099696497',
42+
projectId: 'flutterfire-e2e-tests',
43+
databaseURL:
44+
'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
45+
storageBucket: 'flutterfire-e2e-tests.appspot.com',
46+
);
47+
48+
static const FirebaseOptions ios = FirebaseOptions(
49+
apiKey: 'AIzaSyDooSUGSf63Ghq02_iIhtnmwMDs4HlWS6c',
50+
appId: '1:406099696497:ios:69e46ec5e92b32c83574d0',
51+
messagingSenderId: '406099696497',
52+
projectId: 'flutterfire-e2e-tests',
53+
databaseURL:
54+
'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
55+
storageBucket: 'flutterfire-e2e-tests.appspot.com',
56+
androidClientId:
57+
'406099696497-tvtvuiqogct1gs1s6lh114jeps7hpjm5.apps.googleusercontent.com',
58+
iosClientId:
59+
'406099696497-v19okv5oaniql5uouh7go85uld7pa4mo.apps.googleusercontent.com',
60+
iosBundleId: 'io.flutter.plugins.firebase.functions.example',
61+
);
62+
63+
static const FirebaseOptions macos = FirebaseOptions(
64+
apiKey: 'AIzaSyDooSUGSf63Ghq02_iIhtnmwMDs4HlWS6c',
65+
appId: '1:406099696497:ios:69e46ec5e92b32c83574d0',
66+
messagingSenderId: '406099696497',
67+
projectId: 'flutterfire-e2e-tests',
68+
databaseURL:
69+
'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
70+
storageBucket: 'flutterfire-e2e-tests.appspot.com',
71+
androidClientId:
72+
'406099696497-tvtvuiqogct1gs1s6lh114jeps7hpjm5.apps.googleusercontent.com',
73+
iosClientId:
74+
'406099696497-v19okv5oaniql5uouh7go85uld7pa4mo.apps.googleusercontent.com',
75+
iosBundleId: 'io.flutter.plugins.firebase.functions.example',
76+
);
77+
}

packages/cloud_functions/cloud_functions/example/lib/main.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
import 'dart:core';
66

77
import 'package:cloud_functions/cloud_functions.dart';
8-
import 'package:cloud_functions_example/firebase_config.dart';
8+
import 'package:cloud_functions_example/firebase_options.dart';
99
import 'package:firebase_core/firebase_core.dart';
1010
import 'package:flutter/material.dart';
1111

1212
Future<void> main() async {
1313
WidgetsFlutterBinding.ensureInitialized();
1414

15-
await Firebase.initializeApp(options: DefaultFirebaseConfig.platformOptions);
15+
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
1616

1717
// You should have the Functions Emulator running locally to use it
1818
// https://firebase.google.com/docs/functions/local-emulator

packages/cloud_functions/cloud_functions/lib/cloud_functions.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
library cloud_functions;
77

88
import 'dart:async';
9+
import 'dart:typed_data';
910

1011
import 'package:cloud_functions_platform_interface/cloud_functions_platform_interface.dart';
1112
import 'package:firebase_core/firebase_core.dart';

packages/cloud_functions/cloud_functions/lib/src/https_callable.dart

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,33 @@ class HttpsCallable {
3232
/// the user is also automatically included.
3333
Future<HttpsCallableResult<T>> call<T>([dynamic parameters]) async {
3434
assert(_debugIsValidParameterType(parameters));
35-
return HttpsCallableResult<T>._(await delegate.call(parameters));
35+
36+
Object? updatedParameters;
37+
if (parameters is Map) {
38+
Map update = {};
39+
parameters.forEach((key, value) {
40+
update[key] = _updateRawDataToList(value);
41+
});
42+
updatedParameters = update;
43+
} else if (parameters is List) {
44+
List update = parameters.map(_updateRawDataToList).toList();
45+
updatedParameters = update;
46+
} else {
47+
updatedParameters = _updateRawDataToList(parameters);
48+
}
49+
return HttpsCallableResult<T>._(await delegate.call(updatedParameters));
50+
}
51+
}
52+
53+
dynamic _updateRawDataToList(dynamic value) {
54+
if (value is Uint8List ||
55+
value is Int32List ||
56+
value is Int64List ||
57+
value is Float32List ||
58+
value is Float64List) {
59+
return value.toList();
60+
} else {
61+
return value;
3662
}
3763
}
3864

tests/test_driver/cloud_functions/cloud_functions_e2e.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'dart:typed_data';
6+
57
import 'package:cloud_functions/cloud_functions.dart';
68
import 'package:firebase_core/firebase_core.dart';
79
import 'package:drive/drive.dart';
10+
import 'package:flutter/foundation.dart';
811

912
import '../firebase_default_options.dart';
1013

@@ -84,6 +87,28 @@ void setupTests() {
8487
expect(result.data, equals(data.deepList));
8588
});
8689

90+
test(
91+
'accepts raw data as arguments',
92+
() async {
93+
HttpsCallableResult result = await callable({
94+
'type': 'rawData',
95+
'list': Uint8List(100),
96+
'int': Int32List(39),
97+
'long': Int64List(45),
98+
'float': Float32List(23),
99+
'double': Float64List(1001),
100+
});
101+
final data = result.data;
102+
expect(data['list'], isA<List>());
103+
expect(data['int'], isA<List>());
104+
expect(data['long'], isA<List>());
105+
expect(data['float'], isA<List>());
106+
expect(data['double'], isA<List>());
107+
},
108+
// Int64List is not supported on Web.
109+
skip: kIsWeb,
110+
);
111+
87112
test(
88113
'[HttpsCallableResult.data] should return Map<String, dynamic> type for returned objects',
89114
() async {

0 commit comments

Comments
 (0)