Repository navigation
fix(firestore): work around Xcode 26.2 trait bug - #16944
Conversation
Xcode 26.2 doesn't enable a package's default traits when an Xcode project (.xcodeproj) adds the package by its URL. Every `.when(traits: ["Firestore"])` condition evaluated to false, so FirebaseFirestore wasn't linked, FIRESTORE_TRAIT_ENABLED wasn't defined, and the build failed with the "trait is disabled" #error in FirebaseFirestoreWrap/dummy.m, even though the trait was never turned off. Package.swift dependents and Xcode 26.4+ aren't affected. Route all Firestore trait conditions through two new helpers, firestoreTraitDependencyCondition(platforms:) and firestoreTraitBuildSettingCondition(). On Swift 6.2 (Xcode 26.2), gated by `#if compiler(>=6.3)`, they drop the trait requirement so Firestore is always included and FIRESTORE_TRAIT_ENABLED is always defined. The trait stays declared, because SwiftPM 6.2 fails to resolve dependents that pass `traits:` to a package that declares no traits. Swift 6.3+ keeps the existing trait behavior. Also expand the trait documentation: how to opt out, removing the FirebaseFirestore product afterward, and the Xcode 26.2 limitation.
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. |
Replace the #XXXXX placeholder in the Xcode 26.2 trait fix entry with the PR number, #16944.
Xcode 26.2 doesn't enable a package's default traits when an Xcode project (
.xcodeproj) adds the package by its URL. As a result, every.when(traits: ["Firestore"])condition inPackage.swiftevaluates tofalsefor these apps, even though they never turned the trait off:FirebaseFirestoreand its dependencies (gRPC, Abseil) aren't linked.FIRESTORE_TRAIT_ENABLEDisn't defined, so the build fails with the#errorinSwiftPM-PlatformExclude/FirebaseFirestoreWrap/dummy.m: "FirebaseFirestore was included in your project dependencies, but the 'Firestore' SwiftPM package trait is disabled…"Xcode 26.2 also has no Traits UI (it was added in Xcode 26.4), so affected developers have no workaround. Packages that depend on Firebase in their own
Package.swift, local package references, and Xcode 26.4+ are not affected.Fix
Since we can't require Xcode 26.4 yet,
Package.swiftnow ignores theFirestoretrait on Swift 6.2 (the Swift version in Xcode 26.2):isFirestoreTraitConditionSupported, gated by#if compiler(>=6.3). A manifest can't check the Xcode version, so the Swift compiler version stands in for it.firestoreTraitDependencyCondition(platforms:)andfirestoreTraitBuildSettingCondition(), and routed all 15.when(traits: ["Firestore"])call sites through them (binary and source Firestore). On Swift 6.2 they drop the trait requirement, so Firestore is always linked andFIRESTORE_TRAIT_ENABLEDis always defined. On Swift 6.3+ they return the same conditions as before.Firestoretrait is still declared on Swift 6.2. SwiftPM 6.2 fails to resolve any dependent that passestraits:(eventraits: []) to a package that declares no traits, so removing the declaration would break existing opt-outs.firestoreTraitNamestring constant. In Swift 6 language mode, the helper functions can't read the non-SendablefirestoreTraitglobal.Package.swiftand in Xcode, removing theFirebaseFirestoreproduct afterward, and the Xcode 26.2 limitation.Firestore/CHANGELOG.mdentry.Trade-off
On Swift 6.2, opting out of the
Firestoretrait has no effect, including forswift buildusers. Opting out requires Xcode 26.4 / Swift 6.3 or later. The workaround can be removed once Firebase requires Xcode 26.4.Testing
Reproduced the bug with a minimal package that declares a default-enabled trait and uses it in a
cSettingsdefine, a Swift#ifcheck, and a target dependency. Before the fix, the trait was enabled in every case except one:swift build(root package)xcodebuild(root package)swift buildandxcodebuild).xcodeproj, local package reference.xcodeproj, remote package reference.xcodeproj, remote package referenceAfter applying the same pattern to the reproduction, the
.xcodeprojremote package reference on Xcode 26.2 builds, gets-DFIRESTORE_TRAIT_ENABLED, and builds the trait-conditioned dependency.Also verified:
swift package dump-packagesucceeds with both Xcode 26.2 and 26.4, with and withoutFIREBASE_SOURCE_FIRESTORE. On 26.2 there are no trait conditions; on 26.4 all trait conditions are unchanged.traits: []still resolves.