Skip to content

Commit 3d13d38

Browse files
committed
fix(functions, ios): use concrete NSNull for SDK params when possible
this works better with stricter type-checking in the firebase-ios-sdk API calls and is more correct in general
1 parent 7221dc4 commit 3d13d38

File tree

2 files changed

+89
-56
lines changed

2 files changed

+89
-56
lines changed

packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.m

Lines changed: 87 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,17 @@ @implementation RNFBFunctionsModule
5656
callable.timeoutInterval = [options[@"timeout"] doubleValue];
5757
}
5858

59-
[callable callWithObject:[wrapper valueForKey:@"data"]
59+
// In reality, this value is always null, because we always call it with null data
60+
// on the javascript side for some reason. Check for that case (which should be 100% of the time)
61+
// and set it to an `NSNull` (versus the `Optional<Any>` Swift will see from `valueForKey` so that
62+
// FirebaseFunctions serializer won't have a validation failure for an unknown type.
63+
id data = [wrapper valueForKey:@"data"];
64+
NSLog(@"RNFBFUNCTIONS pulled data from 'wrapper', has type %@", [data class]);
65+
if (data == nil) {
66+
data = [NSNull null];
67+
}
68+
69+
[callable callWithObject:data
6070
completion:^(FIRHTTPSCallableResult *_Nullable result, NSError *_Nullable error) {
6171
if (error) {
6272
NSObject *details = [NSNull null];
@@ -108,7 +118,16 @@ @implementation RNFBFunctionsModule
108118
callable.timeoutInterval = [options[@"timeout"] doubleValue];
109119
}
110120

111-
[callable callWithObject:[wrapper valueForKey:@"data"]
121+
// In reality, this value is always null, because we always call it with null data
122+
// on the javascript side for some reason. Check for that case (which should be 100% of the time)
123+
// and set it to an `NSNull` (versus the `Optional<Any>` Swift will see from `valueForKey` so that
124+
// FirebaseFunctions serializer won't have a validation failure for an unknown type.
125+
id data = [wrapper valueForKey:@"data"];
126+
if (data == nil) {
127+
data = [NSNull null];
128+
}
129+
130+
[callable callWithObject:data
112131
completion:^(FIRHTTPSCallableResult *_Nullable result, NSError *_Nullable error) {
113132
if (error) {
114133
NSObject *details = [NSNull null];
@@ -134,60 +153,72 @@ @implementation RNFBFunctionsModule
134153

135154
- (NSString *)getErrorCodeName:(NSError *)error {
136155
NSString *code = @"UNKNOWN";
137-
switch (error.code) {
138-
case FIRFunctionsErrorCodeOK:
139-
code = @"OK";
140-
break;
141-
case FIRFunctionsErrorCodeCancelled:
142-
code = @"CANCELLED";
143-
break;
144-
case FIRFunctionsErrorCodeUnknown:
145-
code = @"UNKNOWN";
146-
break;
147-
case FIRFunctionsErrorCodeInvalidArgument:
148-
code = @"INVALID_ARGUMENT";
149-
break;
150-
case FIRFunctionsErrorCodeDeadlineExceeded:
151-
code = @"DEADLINE_EXCEEDED";
152-
break;
153-
case FIRFunctionsErrorCodeNotFound:
154-
code = @"NOT_FOUND";
155-
break;
156-
case FIRFunctionsErrorCodeAlreadyExists:
157-
code = @"ALREADY_EXISTS";
158-
break;
159-
case FIRFunctionsErrorCodePermissionDenied:
160-
code = @"PERMISSION_DENIED";
161-
break;
162-
case FIRFunctionsErrorCodeResourceExhausted:
163-
code = @"RESOURCE_EXHAUSTED";
164-
break;
165-
case FIRFunctionsErrorCodeFailedPrecondition:
166-
code = @"FAILED_PRECONDITION";
167-
break;
168-
case FIRFunctionsErrorCodeAborted:
169-
code = @"ABORTED";
170-
break;
171-
case FIRFunctionsErrorCodeOutOfRange:
172-
code = @"OUT_OF_RANGE";
173-
break;
174-
case FIRFunctionsErrorCodeUnimplemented:
175-
code = @"UNIMPLEMENTED";
176-
break;
177-
case FIRFunctionsErrorCodeInternal:
178-
code = @"INTERNAL";
179-
break;
180-
case FIRFunctionsErrorCodeUnavailable:
181-
code = @"UNAVAILABLE";
182-
break;
183-
case FIRFunctionsErrorCodeDataLoss:
184-
code = @"DATA_LOSS";
185-
break;
186-
case FIRFunctionsErrorCodeUnauthenticated:
187-
code = @"UNAUTHENTICATED";
188-
break;
189-
default:
190-
break;
156+
157+
if ([error.domain isEqual:@"com.firebase.functions"]) {
158+
switch (error.code) {
159+
case FIRFunctionsErrorCodeOK:
160+
code = @"OK";
161+
break;
162+
case FIRFunctionsErrorCodeCancelled:
163+
code = @"CANCELLED";
164+
break;
165+
case FIRFunctionsErrorCodeUnknown:
166+
code = @"UNKNOWN";
167+
break;
168+
case FIRFunctionsErrorCodeInvalidArgument:
169+
code = @"INVALID_ARGUMENT";
170+
break;
171+
case FIRFunctionsErrorCodeDeadlineExceeded:
172+
code = @"DEADLINE_EXCEEDED";
173+
break;
174+
case FIRFunctionsErrorCodeNotFound:
175+
code = @"NOT_FOUND";
176+
break;
177+
case FIRFunctionsErrorCodeAlreadyExists:
178+
code = @"ALREADY_EXISTS";
179+
break;
180+
case FIRFunctionsErrorCodePermissionDenied:
181+
code = @"PERMISSION_DENIED";
182+
break;
183+
case FIRFunctionsErrorCodeResourceExhausted:
184+
code = @"RESOURCE_EXHAUSTED";
185+
break;
186+
case FIRFunctionsErrorCodeFailedPrecondition:
187+
code = @"FAILED_PRECONDITION";
188+
break;
189+
case FIRFunctionsErrorCodeAborted:
190+
code = @"ABORTED";
191+
break;
192+
case FIRFunctionsErrorCodeOutOfRange:
193+
code = @"OUT_OF_RANGE";
194+
break;
195+
case FIRFunctionsErrorCodeUnimplemented:
196+
code = @"UNIMPLEMENTED";
197+
break;
198+
case FIRFunctionsErrorCodeInternal:
199+
code = @"INTERNAL";
200+
break;
201+
case FIRFunctionsErrorCodeUnavailable:
202+
code = @"UNAVAILABLE";
203+
break;
204+
case FIRFunctionsErrorCodeDataLoss:
205+
code = @"DATA_LOSS";
206+
break;
207+
case FIRFunctionsErrorCodeUnauthenticated:
208+
code = @"UNAUTHENTICATED";
209+
break;
210+
default:
211+
break;
212+
}
213+
}
214+
if ([error.domain isEqual:@"FirebaseFunctions.FunctionsSerializer.Error"]) {
215+
NSLog(@"RNFBFUNCTIONS error description: %@", error.description);
216+
if ([error.description containsString:@"unsupportedType"]) {
217+
code = @"UNSUPPORTED_TYPE";
218+
}
219+
if ([error.description containsString:@"failedToParseWrappedNumber"]) {
220+
code = @"FAILED_TO_PARSE_WRAPPED_NUMBER";
221+
}
191222
}
192223

193224
return code;

packages/functions/lib/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export const HttpsErrorCode = {
4747
INTERNAL: 'internal',
4848
UNAVAILABLE: 'unavailable',
4949
DATA_LOSS: 'data-loss',
50+
UNSUPPORTED_TYPE: 'unsupported-type',
51+
FAILED_TO_PARSE_WRAPPED_NUMBER: 'failed-to-parse-wrapped-number',
5052
// Web codes are lowercase dasherized.
5153
ok: 'ok',
5254
cancelled: 'cancelled',

0 commit comments

Comments
 (0)