Skip to content

FirebaseAuth.User.providerData getter crashes with SIGTRAP in 12.9.0 #15950

@bryansum

Description

@bryansum

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:

  1. We are pinned to Firebase iOS SDK 12.9.0 via Swift Package Manager.
  2. We have 5 crashes with the same top frame/signature.
  3. The crash happens from different app call sites and on different threads, but always with the same top FirebaseAuth frames.
  4. The crashing access is synchronous and does not call reload() itself.
  5. 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"
      }
    }
  ]
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions