Description
We are seeing production crashes in FirebaseAuth 12.9.0 where the top frame is consistently FirebaseAuth.User.providerData.getter.
Representative stack shape:
User.providerData.getter
User.hasLinkedEmail.getter
- app code that is synchronously reading
Auth.auth().currentUser
In our app we have a synchronous helper that builds a lightweight snapshot of the current auth user. One of the derived fields checks whether the email provider is linked by iterating user.providerData.
What we expected:
Auth.auth().currentUser and user.providerData should be safe to read synchronously from app code if the User type is intended to be thread-safe.
What actually happened:
- We are getting
EXC_BREAKPOINT (SIGTRAP) crashes in production at User.providerData.getter across multiple OS versions and multiple call sites/threads.
After looking at the FirebaseAuth source in 12.9.0, this looks suspicious because:
providerData is implemented as Array(providerDataRaw.values)
providerDataRaw is a plain Swift dictionary
providerDataRaw is mutated in update(withGetAccountInfoResponse:) and other profile update paths
- the
User source file still says This class is thread-safe.
Relevant FirebaseAuth source in 12.9.0:
FirebaseAuth/Sources/Swift/User/User.swift:46-47
FirebaseAuth/Sources/Swift/User/User.swift:1273-1299
FirebaseAuth/Sources/Swift/User/UserProfileUpdate.swift:136-155
FirebaseAuth/Sources/Swift/User/UserProfileUpdate.swift:181-188
This may be a race or another thread-safety issue around internal mutation of cached User state.
Reproducing the issue
We do not yet have a minimal repro. This is from production crash data.
What we know so far:
- We are pinned to Firebase iOS SDK 12.9.0 via Swift Package Manager.
- We have 5 crashes with the same top frame/signature.
- The crash happens from different app call sites and on different threads, but always with the same top FirebaseAuth frames.
- The crashing access is synchronous and does not call
reload() itself.
- The crashing path is reading
providerData to derive whether the email provider is linked.
If useful, I can try to turn this into a standalone repro that repeatedly reads currentUser.providerData while also forcing auth refresh / link / unlink activity.
Firebase SDK Version
12.9.0
Xcode Version
Xcode 26.3 (Build version 17C529)
Installation Method
Swift Package Manager
Firebase Product(s)
Authentication
Firestore
Targeted Platforms
iOS
Relevant Log Output
Representative crash #1:
OS Version: iPhone OS 17.5.1 (21F90)
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Triggered by Thread: 0
Thread 0 Crashed:
0 Locket User.providerData.getter + 188 (User.swift:47)
1 Locket User.hasLinkedEmail.getter + 56 (AuthClientLive.swift:107)
2 Locket closure #3 in variable initialization expression of static AuthClient.liveValue + 356 (AuthClientLive.swift:28)
3 Locket logFirestoreAnalytics(_:parameters:) + 380 (FirestoreLogger.swift:548)
4 Locket logSnapshotListenerFired(id:path:isFromCache:changes:count:) + 1292 (FirestoreLogger.swift:377)
5 Locket closure #1 in FIRQuery.addListener(ref:includeMetadataChanges:listener:) + 616 (FirestoreLogger.swift:621)
6 Locket partial apply for closure #1 in FIRQuery.addListener(ref:includeMetadataChanges:listener:) + 116
7 Locket <deduplicated_symbol> + 80
8 Locket std::__1::__function::__func<-[FIRQuery addSnapshotListenerInternalWithOptions:listener:]::$_0, ...>
9 Locket firebase::firestore::core::EventListener<firebase::firestore::core::ViewSnapshot>::Create(...)
10 Locket firebase::firestore::util::Task::ExecuteAndRelease() + 192
Representative crash #2:
OS Version: iPhone OS 26.3.1 (23D8133)
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Triggered by Thread: 0
Thread 0 Crashed:
0 Locket User.providerData.getter + 188 (User.swift:47)
1 Locket User.hasLinkedEmail.getter + 56 (AuthClientLive.swift:107)
2 Locket closure #3 in variable initialization expression of static AuthClient.liveValue + 356 (AuthClientLive.swift:28)
3 Locket RemoteConfigClient.friendLimitMode.getter + 420 (RemoteConfig+FriendClient.swift:17)
4 Locket closure #1 in closure #1 in closure #1 in LocketRemoteConfig.refresh() + 4204 (LocketRemoteConfig.swift:144)
5 Locket <deduplicated_symbol> + 28
6 libdispatch.dylib _dispatch_call_block_and_release + 32
7 libdispatch.dylib _dispatch_client_callout + 16
8 libdispatch.dylib _dispatch_main_queue_drain.cold.5 + 812
9 libdispatch.dylib _dispatch_main_queue_drain + 180
Representative crash #3:
OS Version: iPhone OS 18.6.2 (22G100)
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Triggered by Thread: 56
Thread 56 Crashed:
0 Locket User.providerData.getter + 188 (User.swift:47)
1 Locket User.hasLinkedEmail.getter + 56 (AuthClientLive.swift:107)
2 Locket closure #3 in variable initialization expression of static AuthClient.liveValue + 356 (AuthClientLive.swift:28)
3 Locket logFirestoreAnalytics(_:parameters:) + 380 (FirestoreLogger.swift:548)
4 Locket logGetDocuments(path:count:isFromCache:source:) + 1252 (FirestoreLogger.swift:451)
5 Locket FIRQuery.get(ref:source:) + 156 (FirestoreLogger.swift:731)
6 Locket closure #5 in variable initialization expression of static HistoryManagerInternalClient.liveValue + 1 (HistoryManagerInternalClientLive.swift:140)
7 Locket HistoryManager.listenForDeletedMoments() + 1 (HistoryManager.swift:726)
8 Locket closure #1 in deletedMomentsListener #1 () in closure #1 in HistoryManager.processFriendsChanges(changes:) + 1 (HistoryManager.swift:503)
We have 2 additional crashes with the same top frames on iOS 17.4.1 and 18.7.6.
If using Swift Package Manager, the project's Package.resolved
Expand Package.resolved snippet
{
"pins" : [
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk.git",
"state" : {
"revision" : "9b3aed4fa6226125305b82d4d86c715bef250785",
"version" : "12.9.0"
}
}
]
}
Description
We are seeing production crashes in FirebaseAuth 12.9.0 where the top frame is consistently
FirebaseAuth.User.providerData.getter.Representative stack shape:
User.providerData.getterUser.hasLinkedEmail.getterAuth.auth().currentUserIn our app we have a synchronous helper that builds a lightweight snapshot of the current auth user. One of the derived fields checks whether the email provider is linked by iterating
user.providerData.What we expected:
Auth.auth().currentUseranduser.providerDatashould be safe to read synchronously from app code if theUsertype is intended to be thread-safe.What actually happened:
EXC_BREAKPOINT (SIGTRAP)crashes in production atUser.providerData.getteracross multiple OS versions and multiple call sites/threads.After looking at the FirebaseAuth source in 12.9.0, this looks suspicious because:
providerDatais implemented asArray(providerDataRaw.values)providerDataRawis a plain Swift dictionaryproviderDataRawis mutated inupdate(withGetAccountInfoResponse:)and other profile update pathsUsersource file still saysThis class is thread-safe.Relevant FirebaseAuth source in 12.9.0:
FirebaseAuth/Sources/Swift/User/User.swift:46-47FirebaseAuth/Sources/Swift/User/User.swift:1273-1299FirebaseAuth/Sources/Swift/User/UserProfileUpdate.swift:136-155FirebaseAuth/Sources/Swift/User/UserProfileUpdate.swift:181-188This may be a race or another thread-safety issue around internal mutation of cached
Userstate.Reproducing the issue
We do not yet have a minimal repro. This is from production crash data.
What we know so far:
reload()itself.providerDatato derive whether the email provider is linked.If useful, I can try to turn this into a standalone repro that repeatedly reads
currentUser.providerDatawhile also forcing auth refresh / link / unlink activity.Firebase SDK Version
12.9.0
Xcode Version
Xcode 26.3 (Build version 17C529)
Installation Method
Swift Package Manager
Firebase Product(s)
Authentication
Firestore
Targeted Platforms
iOS
Relevant Log Output
Representative crash #1:
Representative crash #2:
Representative crash #3:
We have 2 additional crashes with the same top frames on iOS 17.4.1 and 18.7.6.
If using Swift Package Manager, the project's Package.resolved
Expand
Package.resolvedsnippet{ "pins" : [ { "identity" : "firebase-ios-sdk", "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk.git", "state" : { "revision" : "9b3aed4fa6226125305b82d4d86c715bef250785", "version" : "12.9.0" } } ] }