You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In my Swift app, errors returned from Firebase Blocking Functions are not properly handled, resulting in the following generic error message:
Error Domain=FIRAuthErrorDomain Code=17999 "An internal error has
occurred, print and inspect the error details for more information."
UserInfo={NSUnderlyingError=0x600000e8d0b0 {Error Domain=FIRAuthInternalErrorDomain Code=2 "(null)" UserInfo={NSUnderlyingError=0x600000cc2700 {Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did
not start with array or object and option to allow fragments not set. around line 1, column 0."
UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.
around line 1, column 0., NSJSONSerializationErrorIndex=0}}}}, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information., FIRAuthErrorUserInfoNameKey=ERROR_INTERNAL_ERROR}
Blocking function
The blocking function is running on Node.js 20 using beforeUserCreated and throws an error in the following format:
thrownewHttpsError("invalid-argument","invalid email",{code: "invalid-email",message: "Please enter a valid email address to create your account.",});
The expected raw error response from this blocking function should resemble:
BLOCKING_FUNCTION_ERROR_RESPONSE : ((HTTP request to http://127.0.0.1:9999/project-id/us-central1/beforeUserCreated returned HTTP error 400: {"error":{"details":{"code":"invalid-email"},"message":"invalid email","status":"INVALID_ARGUMENT"}}))
The root cause stems from two issues in the Firebase iOS SDK that lead to an improperly formatted error.
Parsing Issue in AuthBackend.swift
In AuthBackend.swift, the SDK attempts to split the error message string by colons. The intent was to separate the initial part (shortErrorMessage) from the remaining part (serverDetailErrorMessage). However, splitting by : inadvertently captures portions of the URL, resulting in a truncated message ((HTTP request to http, which breaks the error handling.
To address this, I propose updating the parsing logic to identify the first colon’s index and split the string at that point, preserving the intended structure:
Hardcoded String Dependency in AuthErrorUtils.swift
In AuthErrorUtils.swift, the blockingCloudFunctionServerResponse function relies on replacing a hardcoded string to extract JSON data from the error. This dependency fails because the string "HTTP Cloud Function returned an error:" is absent, leading to a JSON serialization error.
To avoid hardcoded string dependencies, I suggest using regex to directly capture the JSON object within the error string, making the SDK more resilient to changes. Here is the updated function:
staticfunc blockingCloudFunctionServerResponse(message:String?)->Error{do{
guard let message = message,let match =tryNSRegularExpression(pattern:"\\{.*\\}", options:.dotMatchesLineSeparators).firstMatch(
in: message,
range:NSRange(message.startIndex..., in: message)),let range =Range(match.range, in: message)else{returnerror(code:.blockingCloudFunctionError, message:nil)}letjsonData=String(message[range]).data(using:.utf8)??Data()letjsonDict:[String:Any]?=tryJSONSerialization.jsonObject(with: jsonData)as?[String:Any]leterrorMessage=(jsonDict?["error"]as?[String:Any])?["message"]as?Stringreturnerror(code:.blockingCloudFunctionError, message: errorMessage)}catch{returnJSONSerializationError(underlyingError: error)}}
With this fix, the Blocking Function error should be correctly handled, producing a clear and actionable message:
As recommended in the contribution guide, I wanted to share this approach before opening a pull request to gather any insights or feedback that could help further refine these fixes. Thank you for your time and consideration!
Reproducing the issue
step 1: throw a httpsError in your beforeUserCreated Blocking Cloud Function (can be any blocking function)
step 2: create a user in the swift app and catch the error, here's an example code
@amirandalibi Thanks for sharing the issue and analysis. Your analysis sounds good to me and we would appreciate a pull request including a unit test that demonstrates the issue and fix. Also, my preference would be to use Swift Regular Expression syntax instead of NSRegularExpression.
Description
In my Swift app, errors returned from Firebase Blocking Functions are not properly handled, resulting in the following generic error message:
Blocking function
The blocking function is running on Node.js 20 using
beforeUserCreated
and throws an error in the following format:The expected raw error response from this blocking function should resemble:
The root cause stems from two issues in the Firebase iOS SDK that lead to an improperly formatted error.
In
AuthBackend.swift
, the SDK attempts to split the error message string by colons. The intent was to separate the initial part (shortErrorMessage) from the remaining part (serverDetailErrorMessage). However, splitting by:
inadvertently captures portions of the URL, resulting in a truncated message((HTTP request to http
, which breaks the error handling.Current code
firebase-ios-sdk/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift
Lines 315 to 318 in 32a6788
Suggested Fix
To address this, I propose updating the parsing logic to identify the first colon’s index and split the string at that point, preserving the intended structure:
In
AuthErrorUtils.swift
, theblockingCloudFunctionServerResponse
function relies on replacing a hardcoded string to extract JSON data from the error. This dependency fails because the string"HTTP Cloud Function returned an error:"
is absent, leading to a JSON serialization error.Current code
firebase-ios-sdk/FirebaseAuth/Sources/Swift/Utilities/AuthErrorUtils.swift
Lines 509 to 528 in 32a6788
Suggested Fix
To avoid hardcoded string dependencies, I suggest using regex to directly capture the JSON object within the error string, making the SDK more resilient to changes. Here is the updated function:
With this fix, the Blocking Function error should be correctly handled, producing a clear and actionable message:
As recommended in the contribution guide, I wanted to share this approach before opening a pull request to gather any insights or feedback that could help further refine these fixes. Thank you for your time and consideration!
Reproducing the issue
step 1: throw a
httpsError
in yourbeforeUserCreated
Blocking Cloud Function (can be any blocking function)step 2: create a user in the swift app and catch the error, here's an example code
Firebase SDK Version
11.4.0
Xcode Version
Version 15.4 (15F31d)
Installation Method
Swift Package Manager
Firebase Product(s)
Authentication, Functions
Targeted Platforms
iOS
Relevant Log Output
No response
If using Swift Package Manager, the project's Package.resolved
No response
If using CocoaPods, the project's Podfile.lock
No response
The text was updated successfully, but these errors were encountered: