diff --git a/FirebaseAuth/CHANGELOG.md b/FirebaseAuth/CHANGELOG.md index 01e82591381..b9278b58399 100644 --- a/FirebaseAuth/CHANGELOG.md +++ b/FirebaseAuth/CHANGELOG.md @@ -1,3 +1,6 @@ +# 11.15.0 +- [fixed] Fixed `Sendable` warnings introduced in the Xcode 26 beta. (#14996) + # 11.14.0 - [fixed] Synchronize internal `AuthKeychainServices` class to prevent crashes from concurrent access. (#14835) diff --git a/FirebaseAuth/Sources/Swift/Auth/Auth.swift b/FirebaseAuth/Sources/Swift/Auth/Auth.swift index 1f89d5ddfe4..3cfb87f41cc 100644 --- a/FirebaseAuth/Sources/Swift/Auth/Auth.swift +++ b/FirebaseAuth/Sources/Swift/Auth/Auth.swift @@ -863,29 +863,41 @@ extension Auth: AuthInterop { displayName: nil, idToken: nil, requestConfiguration: self.requestConfiguration) - #if os(iOS) - self.wrapInjectRecaptcha(request: request, - action: AuthRecaptchaAction.signUpPassword) { response, error in - if let error { + Task { + do { + let response = try await self.injectRecaptcha( + request: request, + action: AuthRecaptchaAction.signUpPassword + ) + self.internalCreateUserWithEmail( + request: request, + inResponse: response, + decoratedCallback: decoratedCallback + ) + } catch { DispatchQueue.main.async { decoratedCallback(.failure(error)) } return } - self.internalCreateUserWithEmail(request: request, inResponse: response, - decoratedCallback: decoratedCallback) } #else - self.internalCreateUserWithEmail(request: request, decoratedCallback: decoratedCallback) + self.internalCreateUserWithEmail( + request: request, + decoratedCallback: decoratedCallback + ) #endif } } - func internalCreateUserWithEmail(request: SignUpNewUserRequest, - inResponse: SignUpNewUserResponse? = nil, - decoratedCallback: @escaping (Result) - -> Void) { + private func internalCreateUserWithEmail(request: SignUpNewUserRequest, + inResponse: SignUpNewUserResponse? = nil, + decoratedCallback: @escaping (Result< + AuthDataResult, + Error + >) + -> Void) { Task { do { var response: SignUpNewUserResponse @@ -1161,12 +1173,15 @@ extension Auth: AuthInterop { requestConfiguration: self.requestConfiguration ) #if os(iOS) - self.wrapInjectRecaptcha(request: request, - action: AuthRecaptchaAction.getOobCode) { result, error in - if let completion { - DispatchQueue.main.async { - completion(error) - } + Task { + do { + _ = try await self.injectRecaptcha( + request: request, + action: AuthRecaptchaAction.getOobCode + ) + Auth.wrapMainAsync(completion, nil) + } catch { + Auth.wrapMainAsync(completion, error) } } #else @@ -1234,12 +1249,15 @@ extension Auth: AuthInterop { requestConfiguration: self.requestConfiguration ) #if os(iOS) - self.wrapInjectRecaptcha(request: request, - action: AuthRecaptchaAction.getOobCode) { result, error in - if let completion { - DispatchQueue.main.async { - completion(error) - } + Task { + do { + _ = try await self.injectRecaptcha( + request: request, + action: AuthRecaptchaAction.getOobCode + ) + Auth.wrapMainAsync(completion, nil) + } catch { + Auth.wrapMainAsync(completion, error) } } #else @@ -2289,21 +2307,6 @@ extension Auth: AuthInterop { } #if os(iOS) - private func wrapInjectRecaptcha(request: T, - action: AuthRecaptchaAction, - _ callback: @escaping ( - (T.Response?, Error?) -> Void - )) { - Task { - do { - let response = try await injectRecaptcha(request: request, action: action) - callback(response, nil) - } catch { - callback(nil, error) - } - } - } - func injectRecaptcha(request: T, action: AuthRecaptchaAction) async throws -> T .Response { diff --git a/FirebaseAuth/Tests/Unit/Fakes/FakeBackendRPCIssuer.swift b/FirebaseAuth/Tests/Unit/Fakes/FakeBackendRPCIssuer.swift index ec931c0c859..a3e7d12db48 100644 --- a/FirebaseAuth/Tests/Unit/Fakes/FakeBackendRPCIssuer.swift +++ b/FirebaseAuth/Tests/Unit/Fakes/FakeBackendRPCIssuer.swift @@ -153,13 +153,15 @@ final class FakeBackendRPCIssuer: AuthBackendRPCIssuerProtocol, @unchecked Senda requestData = body // Use the real implementation so that the complete request can // be verified during testing. + let requestURL = request.requestURL() + let requestConfiguration = request.requestConfiguration() completeRequest = Task { await AuthBackend .request( - for: request.requestURL(), + for: requestURL, httpMethod: requestData == nil ? "GET" : "POST", contentType: contentType, - requestConfiguration: request.requestConfiguration() + requestConfiguration: requestConfiguration ) } decodedRequest = try? JSONSerialization.jsonObject(with: body) as? [String: Any]