Skip to content

Commit 79f74fa

Browse files
committed
fix: Replace async let with Task to work around Swift 6.3 regression (swiftlang/swift#87481)
Backport of firebase#15991 to 12.11.0. Fixes SIGABRT: freed pointer was not the last allocation in release builds. Changes: - FunctionsContext.swift: 3 async let -> Task {} + .value - AuthBackend.swift: 2 async let -> Task {} + .value
1 parent 5254890 commit 79f74fa

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,16 @@ final class AuthBackend: AuthBackendProtocol {
6464
httpMethod: String,
6565
contentType: String,
6666
requestConfiguration: AuthRequestConfiguration) async -> URLRequest {
67+
// Previously, this section uses `async let`, but that was changed for a
68+
// `Task`-based approach to work around a Swift 6.3 regression in Xcode 26.4.
69+
// - Context: https://github.com/firebase/firebase-ios-sdk/issues/15974
6770
// Kick off tasks for the async header values.
68-
async let heartbeatsHeaderValue = requestConfiguration.heartbeatLogger?.asyncHeaderValue()
69-
async let appCheckTokenHeaderValue = requestConfiguration.appCheck?
70-
.getToken(forcingRefresh: false)
71-
71+
let heartbeatsHeaderValue = Task {
72+
await requestConfiguration.heartbeatLogger?.asyncHeaderValue()
73+
}
74+
let appCheckTokenHeaderValue = Task {
75+
await requestConfiguration.appCheck?.getToken(forcingRefresh: false)
76+
}
7277
var request = URLRequest(url: url)
7378
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
7479
let additionalFrameworkMarker = requestConfiguration.additionalFrameworkMarker
@@ -86,8 +91,8 @@ final class AuthBackend: AuthBackendProtocol {
8691
request.setValue(languageCode, forHTTPHeaderField: "X-Firebase-Locale")
8792
}
8893
// Wait for the async header values.
89-
await request.setValue(heartbeatsHeaderValue, forHTTPHeaderField: "X-Firebase-Client")
90-
if let tokenResult = await appCheckTokenHeaderValue {
94+
await request.setValue(heartbeatsHeaderValue.value, forHTTPHeaderField: "X-Firebase-Client")
95+
if let tokenResult = await appCheckTokenHeaderValue.value {
9196
if let error = tokenResult.error {
9297
AuthLog.logWarning(code: "I-AUT000018",
9398
message: "Error getting App Check token; using placeholder " +

FirebaseFunctions/Sources/Internal/FunctionsContext.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,20 @@ struct FunctionsContextProvider: Sendable {
3737
}
3838

3939
func context(options: HTTPSCallableOptions?) async throws -> FunctionsContext {
40-
async let authToken = auth?.getToken(forcingRefresh: false)
41-
async let appCheckToken = getAppCheckToken(options: options)
42-
async let limitedUseAppCheckToken = getLimitedUseAppCheckToken(options: options)
40+
// Previously, this section uses `async let`, but that was changed for a
41+
// `Task`-based approach to work around Swift regression in Xcode 26.4.
42+
// - Context: https://github.com/firebase/firebase-ios-sdk/issues/15974
43+
let authToken = Task { try await auth?.getToken(forcingRefresh: false) }
44+
let appCheckToken = Task { await getAppCheckToken(options: options) }
45+
let limitedUseAppCheckToken = Task { await getLimitedUseAppCheckToken(options: options) }
4346

4447
// Only `authToken` is throwing, but the formatter script removes the `try`
4548
// from `try authToken` and puts it in front of the initializer call.
46-
return try await FunctionsContext(
47-
authToken: authToken,
49+
return try FunctionsContext(
50+
authToken: await authToken.value,
4851
fcmToken: messaging?.fcmToken,
49-
appCheckToken: appCheckToken,
50-
limitedUseAppCheckToken: limitedUseAppCheckToken
52+
appCheckToken: await appCheckToken.value,
53+
limitedUseAppCheckToken: await limitedUseAppCheckToken.value
5154
)
5255
}
5356

0 commit comments

Comments
 (0)