@@ -31,8 +31,7 @@ protocol AuthBackendRPCIssuer: NSObjectProtocol {
31
31
/// on the auth global work queue in the future.
32
32
func asyncCallToURL< T: AuthRPCRequest > ( with request: T ,
33
33
body: Data ? ,
34
- contentType: String ,
35
- completionHandler: @escaping ( ( Data ? , Error ? ) -> Void ) )
34
+ contentType: String ) async -> ( Data ? , Error ? )
36
35
}
37
36
38
37
@available ( iOS 13 , tvOS 13 , macOS 10 . 15 , macCatalyst 13 , watchOS 7 , * )
@@ -51,20 +50,22 @@ class AuthBackendRPCIssuerImplementation: NSObject, AuthBackendRPCIssuer {
51
50
52
51
func asyncCallToURL< T: AuthRPCRequest > ( with request: T ,
53
52
body: Data ? ,
54
- contentType: String ,
55
- completionHandler: @escaping ( ( Data ? , Error ? )
56
- -> Void ) ) {
53
+ contentType: String ) async -> ( Data ? , Error ? ) {
57
54
let requestConfiguration = request. requestConfiguration ( )
58
- AuthBackend . request ( withURL: request. requestURL ( ) ,
59
- contentType: contentType,
60
- requestConfiguration: requestConfiguration) { request in
61
- let fetcher = self . fetcherService. fetcher ( with: request)
62
- if let _ = requestConfiguration. emulatorHostAndPort {
63
- fetcher. allowLocalhostRequest = true
64
- fetcher. allowedInsecureSchemes = [ " http " ]
55
+ let request = await AuthBackend . request ( withURL: request. requestURL ( ) ,
56
+ contentType: contentType,
57
+ requestConfiguration: requestConfiguration)
58
+ let fetcher = fetcherService. fetcher ( with: request)
59
+ if let _ = requestConfiguration. emulatorHostAndPort {
60
+ fetcher. allowLocalhostRequest = true
61
+ fetcher. allowedInsecureSchemes = [ " http " ]
62
+ }
63
+ fetcher. bodyData = body
64
+
65
+ return await withUnsafeContinuation { continuation in
66
+ fetcher. beginFetch { data, error in
67
+ continuation. resume ( returning: ( data, error) )
65
68
}
66
- fetcher. bodyData = body
67
- fetcher. beginFetch ( completionHandler: completionHandler)
68
69
}
69
70
}
70
71
}
@@ -98,8 +99,7 @@ class AuthBackend: NSObject {
98
99
99
100
class func request( withURL url: URL ,
100
101
contentType: String ,
101
- requestConfiguration: AuthRequestConfiguration ,
102
- completion: @escaping ( URLRequest ) -> Void ) {
102
+ requestConfiguration: AuthRequestConfiguration ) async -> URLRequest {
103
103
var request = URLRequest ( url: url)
104
104
request. setValue ( contentType, forHTTPHeaderField: " Content-Type " )
105
105
let additionalFrameworkMarker = requestConfiguration
@@ -121,18 +121,15 @@ class AuthBackend: NSObject {
121
121
request. setValue ( languageCode, forHTTPHeaderField: " X-Firebase-Locale " )
122
122
}
123
123
if let appCheck = requestConfiguration. appCheck {
124
- appCheck. getToken ( forcingRefresh: false ) { tokenResult in
125
- if let error = tokenResult. error {
126
- AuthLog . logWarning ( code: " I-AUT000018 " ,
127
- message: " Error getting App Check token; using placeholder " +
128
- " token instead. Error: \( error) " )
129
- }
130
- request. setValue ( tokenResult. token, forHTTPHeaderField: " X-Firebase-AppCheck " )
131
- completion ( request)
124
+ let tokenResult = await appCheck. getToken ( forcingRefresh: false )
125
+ if let error = tokenResult. error {
126
+ AuthLog . logWarning ( code: " I-AUT000018 " ,
127
+ message: " Error getting App Check token; using placeholder " +
128
+ " token instead. Error: \( error) " )
132
129
}
133
- } else {
134
- completion ( request)
130
+ request. setValue ( tokenResult. token, forHTTPHeaderField: " X-Firebase-AppCheck " )
135
131
}
132
+ return request
136
133
}
137
134
}
138
135
@@ -270,135 +267,104 @@ private class AuthBackendRPCImplementation: NSObject, AuthBackendImplementation
270
267
throw AuthErrorUtils . JSONSerializationErrorForUnencodableType ( )
271
268
}
272
269
}
273
- return try await withCheckedThrowingContinuation { continuation in
274
- rpcIssuer
275
- . asyncCallToURL ( with: request, body: bodyData, contentType: " application/json " ) {
276
- data, error in
277
- // If there is an error with no body data at all, then this must be a
278
- // network error.
279
- guard let data = data else {
280
- if let error = error {
281
- continuation. resume ( throwing: AuthErrorUtils . networkError ( underlyingError: error) )
282
- return
283
- } else {
284
- // TODO: this was ignored before
285
- fatalError ( " Auth Internal error: RPC call didn't return data or an error. " )
286
- }
287
- }
288
- // Try to decode the HTTP response data which may contain either a
289
- // successful response or error message.
290
- var dictionary : [ String : AnyHashable ]
291
- do {
292
- let rawDecode = try JSONSerialization . jsonObject ( with: data,
293
- options: JSONSerialization
294
- . ReadingOptions
295
- . mutableLeaves)
296
- guard let decodedDictionary = rawDecode as? [ String : AnyHashable ] else {
297
- if error != nil {
298
- continuation. resume (
299
- throwing: AuthErrorUtils . unexpectedErrorResponse ( deserializedResponse: rawDecode,
300
- underlyingError: error)
301
- )
302
- return
303
- } else {
304
- continuation. resume (
305
- throwing: AuthErrorUtils . unexpectedResponse ( deserializedResponse: rawDecode)
306
- )
307
- return
308
- }
309
- }
310
- dictionary = decodedDictionary
311
- } catch let jsonError {
312
- if error != nil {
313
- // We have an error, but we couldn't decode the body, so we have no
314
- // additional information other than the raw response and the
315
- // original NSError (the jsonError is inferred by the error code
316
- // (AuthErrorCodeUnexpectedHTTPResponse, and is irrelevant.)
317
- continuation. resume (
318
- throwing: AuthErrorUtils . unexpectedErrorResponse (
319
- data: data,
320
- underlyingError: error
321
- )
322
- )
323
- return
324
- } else {
325
- // This is supposed to be a "successful" response, but we couldn't
326
- // deserialize the body.
327
- continuation. resume (
328
- throwing: AuthErrorUtils . unexpectedResponse ( data: data, underlyingError: jsonError)
329
- )
330
- return
331
- }
332
- }
270
+ let ( data, error) = await rpcIssuer
271
+ . asyncCallToURL ( with: request, body: bodyData, contentType: " application/json " )
272
+ // If there is an error with no body data at all, then this must be a
273
+ // network error.
274
+ guard let data = data else {
275
+ if let error = error {
276
+ throw AuthErrorUtils . networkError ( underlyingError: error)
277
+ } else {
278
+ // TODO: this was ignored before
279
+ fatalError ( " Auth Internal error: RPC call didn't return data or an error. " )
280
+ }
281
+ }
282
+ // Try to decode the HTTP response data which may contain either a
283
+ // successful response or error message.
284
+ var dictionary : [ String : AnyHashable ]
285
+ var rawDecode : Any
286
+ do {
287
+ rawDecode = try JSONSerialization . jsonObject (
288
+ with: data, options: JSONSerialization . ReadingOptions. mutableLeaves
289
+ )
290
+ } catch let jsonError {
291
+ if error != nil {
292
+ // We have an error, but we couldn't decode the body, so we have no
293
+ // additional information other than the raw response and the
294
+ // original NSError (the jsonError is inferred by the error code
295
+ // (AuthErrorCodeUnexpectedHTTPResponse, and is irrelevant.)
296
+ throw AuthErrorUtils . unexpectedErrorResponse ( data: data, underlyingError: error)
297
+ } else {
298
+ // This is supposed to be a "successful" response, but we couldn't
299
+ // deserialize the body.
300
+ throw AuthErrorUtils . unexpectedResponse ( data: data, underlyingError: jsonError)
301
+ }
302
+ }
303
+ guard let decodedDictionary = rawDecode as? [ String : AnyHashable ] else {
304
+ if error != nil {
305
+ throw AuthErrorUtils . unexpectedErrorResponse ( deserializedResponse: rawDecode,
306
+ underlyingError: error)
307
+ } else {
308
+ throw AuthErrorUtils . unexpectedResponse ( deserializedResponse: rawDecode)
309
+ }
310
+ }
311
+ dictionary = decodedDictionary
333
312
334
- let response = T . Response ( )
313
+ let response = T . Response ( )
335
314
336
- // At this point we either have an error with successfully decoded
337
- // details in the body, or we have a response which must pass further
338
- // validation before we know it's truly successful. We deal with the
339
- // case where we have an error with successfully decoded error details
340
- // first:
341
- if error != nil {
342
- if let errorDictionary = dictionary [ " error " ] as? [ String : AnyHashable ] {
343
- if let errorMessage = errorDictionary [ " message " ] as? String {
344
- if let clientError = AuthBackendRPCImplementation . clientError (
345
- withServerErrorMessage: errorMessage,
346
- errorDictionary: errorDictionary,
347
- response: response,
348
- error: error
349
- ) {
350
- continuation. resume ( throwing: clientError)
351
- return
352
- }
353
- }
354
- // Not a message we know, return the message directly.
355
- continuation. resume (
356
- throwing: AuthErrorUtils . unexpectedErrorResponse (
357
- deserializedResponse: errorDictionary,
358
- underlyingError: error
359
- )
360
- )
361
- return
362
- }
363
- // No error message at all, return the decoded response.
364
- continuation. resume (
365
- throwing: AuthErrorUtils
366
- . unexpectedErrorResponse ( deserializedResponse: dictionary, underlyingError: error)
367
- )
368
- return
315
+ // At this point we either have an error with successfully decoded
316
+ // details in the body, or we have a response which must pass further
317
+ // validation before we know it's truly successful. We deal with the
318
+ // case where we have an error with successfully decoded error details
319
+ // first:
320
+ if error != nil {
321
+ if let errorDictionary = dictionary [ " error " ] as? [ String : AnyHashable ] {
322
+ if let errorMessage = errorDictionary [ " message " ] as? String {
323
+ if let clientError = AuthBackendRPCImplementation . clientError (
324
+ withServerErrorMessage: errorMessage,
325
+ errorDictionary: errorDictionary,
326
+ response: response,
327
+ error: error
328
+ ) {
329
+ throw clientError
369
330
}
331
+ }
332
+ // Not a message we know, return the message directly.
333
+ throw AuthErrorUtils . unexpectedErrorResponse (
334
+ deserializedResponse: errorDictionary,
335
+ underlyingError: error
336
+ )
337
+ }
338
+ // No error message at all, return the decoded response.
339
+ throw AuthErrorUtils
340
+ . unexpectedErrorResponse ( deserializedResponse: dictionary, underlyingError: error)
341
+ }
370
342
371
- // Finally, we try to populate the response object with the JSON values.
372
- do {
373
- try response. setFields ( dictionary: dictionary)
374
- } catch {
375
- continuation. resume (
376
- throwing: AuthErrorUtils
377
- . RPCResponseDecodingError ( deserializedResponse: dictionary, underlyingError: error)
378
- )
379
- return
380
- }
381
- // In case returnIDPCredential of a verifyAssertion request is set to
382
- // @YES, the server may return a 200 with a response that may contain a
383
- // server error.
384
- if let verifyAssertionRequest = request as? VerifyAssertionRequest {
385
- if verifyAssertionRequest. returnIDPCredential {
386
- if let errorMessage = dictionary [ " errorMessage " ] as? String {
387
- if let clientError = AuthBackendRPCImplementation . clientError (
388
- withServerErrorMessage: errorMessage,
389
- errorDictionary: dictionary,
390
- response: response,
391
- error: error
392
- ) {
393
- continuation. resume ( throwing: clientError)
394
- return
395
- }
396
- }
397
- }
343
+ // Finally, we try to populate the response object with the JSON values.
344
+ do {
345
+ try response. setFields ( dictionary: dictionary)
346
+ } catch {
347
+ throw AuthErrorUtils
348
+ . RPCResponseDecodingError ( deserializedResponse: dictionary, underlyingError: error)
349
+ }
350
+ // In case returnIDPCredential of a verifyAssertion request is set to
351
+ // @YES, the server may return a 200 with a response that may contain a
352
+ // server error.
353
+ if let verifyAssertionRequest = request as? VerifyAssertionRequest {
354
+ if verifyAssertionRequest. returnIDPCredential {
355
+ if let errorMessage = dictionary [ " errorMessage " ] as? String {
356
+ if let clientError = AuthBackendRPCImplementation . clientError (
357
+ withServerErrorMessage: errorMessage,
358
+ errorDictionary: dictionary,
359
+ response: response,
360
+ error: error
361
+ ) {
362
+ throw clientError
398
363
}
399
- continuation. resume ( returning: response)
400
364
}
365
+ }
401
366
}
367
+ return response
402
368
}
403
369
404
370
private class func clientError( withServerErrorMessage serverErrorMessage: String ,
0 commit comments