Skip to content

fix(firestore): work around Xcode 26.2 trait bug - #16944

Merged
andrewheard merged 3 commits into
mainfrom
ah/spm-firestore-trait-fix
Oct 27, 2026
Merged

andrewheard merged 3 commits into
mainfrom
ah/spm-firestore-trait-fix

Conversation

@andrewheard

Copy link
Copy Markdown
Contributor

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 in Package.swift evaluates to false for these apps, even though they never turned the trait off:

  • FirebaseFirestore and its dependencies (gRPC, Abseil) aren't linked.
  • FIRESTORE_TRAIT_ENABLED isn't defined, so the build fails with the #error in SwiftPM-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.swift now ignores the Firestore trait on Swift 6.2 (the Swift version in Xcode 26.2):

  • Added isFirestoreTraitConditionSupported, gated by #if compiler(>=6.3). A manifest can't check the Xcode version, so the Swift compiler version stands in for it.
  • Added two helpers, firestoreTraitDependencyCondition(platforms:) and firestoreTraitBuildSettingCondition(), 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 and FIRESTORE_TRAIT_ENABLED is always defined. On Swift 6.3+ they return the same conditions as before.
  • The Firestore trait is still declared on Swift 6.2. SwiftPM 6.2 fails to resolve any dependent that passes traits: (even traits: []) to a package that declares no traits, so removing the declaration would break existing opt-outs.
  • Added a firestoreTraitName string constant. In Swift 6 language mode, the helper functions can't read the non-Sendable firestoreTrait global.
  • Expanded the trait documentation: how to opt out in Package.swift and in Xcode, removing the FirebaseFirestore product afterward, and the Xcode 26.2 limitation.
  • Added a Firestore/CHANGELOG.md entry.

Trade-off

On Swift 6.2, opting out of the Firestore trait has no effect, including for swift build users. 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 cSettings define, a Swift #if check, and a target dependency. Before the fix, the trait was enabled in every case except one:

Consumer Xcode Trait enabled?
swift build (root package) 26.2 ✅
xcodebuild (root package) 26.2 ✅
Package dependency, by path and by URL (swift build and xcodebuild) 26.2 ✅
.xcodeproj, local package reference 26.2 ✅
.xcodeproj, remote package reference 26.2 ❌
.xcodeproj, remote package reference 26.4 ✅

After applying the same pattern to the reproduction, the .xcodeproj remote package reference on Xcode 26.2 builds, gets -DFIRESTORE_TRAIT_ENABLED, and builds the trait-conditioned dependency.

Also verified:

  • swift package dump-package succeeds with both Xcode 26.2 and 26.4, with and without FIREBASE_SOURCE_FIRESTORE. On 26.2 there are no trait conditions; on 26.4 all trait conditions are unchanged.
  • On Swift 6.2, a dependent passing traits: [] still resolves.

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.
@gemini-code-assist

Copy link
Copy Markdown
Contributor
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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.
@andrewheard andrewheard added this to the 13.2.0 - M189 milestone Oct 27, 2026
@andrewheard
andrewheard marked this pull request as ready for review October 27, 2026 19:31
@andrewheard
andrewheard merged commit 854b8ae into main Oct 27, 2026
98 checks passed
@andrewheard
andrewheard deleted the ah/spm-firestore-trait-fix branch October 27, 2026 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants