mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
feat(spm): add trait to opt out of Firestore (#16684)
Add support for Swift Package Traits (SE-0450) in Package.swift by introducing a default-enabled "Firestore" trait. Previously, depending on the firebase-ios-sdk Swift package resolved and downloaded Cloud Firestore and its heavy underlying dependencies (gRPC, Abseil, and prebuilt binary artifacts), even if an application only used lightweight Firebase products (such as Auth, Crashlytics, or Remote Config). With package traits, developers can now opt out of Cloud Firestore in their Package.swift (via `traits: []`) or through Xcode 26.4+'s Package Dependencies UI, pruning heavy dependencies and speeding up package resolution while preserving full backwards compatibility: - Define the "Firestore" trait in Package.swift, enabled by default in `packageTraits`. - Gate source and binary Firestore target dependencies (abseil, gRPC, FirebaseFirestoreInternalWrapper, FirebaseFirestoreCombineSwift) on `.when(traits: ["Firestore"])`. - Add `FIRESTORE_TRAIT_ENABLED` C preprocessor macro via target cSettings on `FirebaseFirestoreTarget` and `objc-import-test` to enable conditional compilation for Clang targets when the trait is active. - Provide a clear compile-time `#error` diagnostic in `dummy.m` if an app target links Firestore without enabling the trait. - Gate conditional imports in integration test targets (`swift-test` and `objc-import-test`) so test suites pass both with default traits and with `--disable-default-traits`. - Opt out of default traits in `FirebaseAITestApp` (in project.pbxproj), validating Xcode trait opt-out and avoiding Firestore dependencies for AI Logic integration tests. - Add release notes and Xcode opt-out instructions to changelogs in `FirebaseCore/CHANGELOG.md` and `Firestore/CHANGELOG.md`.
This commit is contained in:
1 parent
1e5ea691ce
commit
54e836b780
8 files changed
+95
-23
No files matched your search
@@ -509,6 +509,8 @@
|
||||
86E850592DBAFBC3002E8D94 /* XCLocalSwiftPackageReference "../../.." */ = {
|
||||
isa = XCLocalSwiftPackageReference;
|
||||
relativePath = ../../..;
|
||||
traits = (
|
||||
);
|
||||
};
|
||||
/* End XCLocalSwiftPackageReference section */
|
||||
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
# Firebase 13.0.0
|
||||
- [feature] Added support for Swift Package Traits (SE-0450) to allow developers
|
||||
to opt out of unused features and prune heavy dependencies. To opt out of
|
||||
Firestore in Xcode: select your project -> **Package Dependencies**, and in
|
||||
the **Traits** column for Firebase, uncheck `default` and check only the ones
|
||||
you want, if any (it will show `None` if no traits are enabled). (#16684)
|
||||
- [changed] **Breaking change**: Firebase's minimum supported versions have
|
||||
updated for the following platforms:
|
||||
- | Platform | Firebase 13 |
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
APIs.
|
||||
- [feature] Adds support for the following new types: `MinKey`, `MaxKey`, `RegexValue`,
|
||||
`Int32Value`, `Decimal128Value`, `BSONObjectId`, `BSONTimestamp`, and `BSONBinaryData`. (#16265)
|
||||
- [changed] Added the `Firestore` package trait to `Package.swift`.
|
||||
Cloud Firestore support now requires the trait to be enabled (it is enabled
|
||||
by default). Developers can opt out of the trait to avoid downloading
|
||||
Firestore's underlying dependencies (such as gRPC and Abseil). (#16684)
|
||||
|
||||
# 12.19.0
|
||||
- [feature] Added support for `minimum` and `maximum` FieldValue operations [#16159].
|
||||
|
||||
+68
-22
@@ -20,12 +20,42 @@ import PackageDescription
|
||||
|
||||
let firebaseVersion = "13.0.0"
|
||||
|
||||
/// If you don't use Firestore in your app, you can disable the "Firestore" trait to reduce
|
||||
/// the number of dependencies fetched by SwiftPM during package resolution.
|
||||
let firestoreTrait = Trait(
|
||||
name: "Firestore",
|
||||
description: "Enables Firestore support and its underlying dependencies (gRPC, Abseil)."
|
||||
)
|
||||
|
||||
/// Package traits allow developers to opt out of features, including their dependencies.
|
||||
///
|
||||
/// In a `Package.swift`:
|
||||
/// ```swift
|
||||
/// .package(
|
||||
/// url: "https://github.com/firebase/firebase-ios-sdk.git",
|
||||
/// from: "13.0.0",
|
||||
/// traits: [
|
||||
/// // Leave empty (or list only non-Firestore traits) to opt out.
|
||||
/// ]
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// In Xcode (26.4+):
|
||||
/// - Select your project -> Package Dependencies -> in the Traits dropdown for Firebase,
|
||||
/// uncheck any unwanted traits.
|
||||
let packageTraits = Set<Trait>([
|
||||
firestoreTrait,
|
||||
// All traits are enabled by default.
|
||||
.default(enabledTraits: [firestoreTrait.name]),
|
||||
])
|
||||
|
||||
let shouldUseSourceFirestore = Context.environment["FIREBASE_SOURCE_FIRESTORE"] != nil
|
||||
|
||||
let package = Package(
|
||||
name: "Firebase",
|
||||
platforms: [.iOS(.v15), .macCatalyst(.v15), .macOS(.v11), .tvOS(.v15), .watchOS(.v8)],
|
||||
products: packageProducts(),
|
||||
traits: packageTraits,
|
||||
dependencies: packageDependencies(),
|
||||
targets: packageTargets(),
|
||||
cxxLanguageStandard: CXXLanguageStandard.gnucxx17
|
||||
@@ -533,7 +563,7 @@ func packageTargets() -> [Target] {
|
||||
.target(
|
||||
name: "FirebaseFirestoreCombineSwift",
|
||||
dependencies: [
|
||||
"FirebaseFirestoreTarget",
|
||||
.target(name: "FirebaseFirestoreTarget", condition: .when(traits: ["Firestore"])),
|
||||
],
|
||||
path: "FirebaseCombineSwift/Sources/Firestore"
|
||||
),
|
||||
@@ -1151,13 +1181,15 @@ func packageTargets() -> [Target] {
|
||||
.target(name: "FirebaseAppDistribution",
|
||||
condition: .when(platforms: [.iOS])),
|
||||
"FirebaseAuthCombineSwift",
|
||||
"FirebaseFirestoreCombineSwift",
|
||||
.target(name: "FirebaseFirestoreCombineSwift",
|
||||
condition: .when(traits: ["Firestore"])),
|
||||
"FirebaseFunctionsCombineSwift",
|
||||
"FirebaseStorageCombineSwift",
|
||||
"FirebaseCrashlytics",
|
||||
"FirebaseCore",
|
||||
"FirebaseDatabase",
|
||||
"FirebaseFirestoreTarget",
|
||||
.target(name: "FirebaseFirestoreTarget",
|
||||
condition: .when(traits: ["Firestore"])),
|
||||
"FirebaseFunctions",
|
||||
.target(name: "FirebaseInAppMessaging",
|
||||
condition: .when(platforms: [.iOS, .tvOS])),
|
||||
@@ -1198,7 +1230,8 @@ func packageTargets() -> [Target] {
|
||||
"FirebaseCrashlytics",
|
||||
"FirebaseCore",
|
||||
"FirebaseDatabase",
|
||||
"FirebaseFirestoreTarget",
|
||||
.target(name: "FirebaseFirestoreTarget",
|
||||
condition: .when(traits: ["Firestore"])),
|
||||
"FirebaseFunctions",
|
||||
.target(name: "FirebaseInAppMessaging",
|
||||
condition: .when(platforms: [.iOS, .tvOS])),
|
||||
@@ -1209,7 +1242,8 @@ func packageTargets() -> [Target] {
|
||||
"FirebaseRemoteConfig",
|
||||
"FirebaseStorage",
|
||||
],
|
||||
path: "SwiftPMTests/objc-import-test"
|
||||
path: "SwiftPMTests/objc-import-test",
|
||||
cSettings: [.define("FIRESTORE_TRAIT_ENABLED", .when(traits: ["Firestore"]))]
|
||||
),
|
||||
.testTarget(
|
||||
name: "version-test",
|
||||
@@ -1447,24 +1481,30 @@ func firestoreWrapperTarget() -> Target {
|
||||
if shouldUseSourceFirestore {
|
||||
return .target(
|
||||
name: "FirebaseFirestoreTarget",
|
||||
dependencies: [.target(name: "FirebaseFirestore",
|
||||
condition: .when(platforms: [
|
||||
.iOS,
|
||||
.tvOS,
|
||||
.macOS,
|
||||
.visionOS,
|
||||
.macCatalyst,
|
||||
]))],
|
||||
path: "SwiftPM-PlatformExclude/FirebaseFirestoreWrap"
|
||||
dependencies: [
|
||||
.target(
|
||||
name: "FirebaseFirestore",
|
||||
condition: .when(
|
||||
platforms: [.iOS, .tvOS, .macOS, .visionOS, .macCatalyst],
|
||||
traits: ["Firestore"]
|
||||
)
|
||||
),
|
||||
],
|
||||
path: "SwiftPM-PlatformExclude/FirebaseFirestoreWrap",
|
||||
cSettings: [.define("FIRESTORE_TRAIT_ENABLED", .when(traits: ["Firestore"]))]
|
||||
)
|
||||
}
|
||||
|
||||
return .target(
|
||||
name: "FirebaseFirestoreTarget",
|
||||
dependencies: [.target(name: "FirebaseFirestore",
|
||||
condition: .when(platforms: [.iOS, .tvOS, .macOS, .macCatalyst]))],
|
||||
condition: .when(platforms: [.iOS, .tvOS, .macOS, .macCatalyst],
|
||||
traits: ["Firestore"]))],
|
||||
path: "SwiftPM-PlatformExclude/FirebaseFirestoreWrap",
|
||||
cSettings: [.define("FIREBASE_BINARY_FIRESTORE", to: "1")]
|
||||
cSettings: [
|
||||
.define("FIREBASE_BINARY_FIRESTORE", to: "1"),
|
||||
.define("FIRESTORE_TRAIT_ENABLED", .when(traits: ["Firestore"])),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1478,8 +1518,10 @@ func firestoreTargets() -> [Target] {
|
||||
"FirebaseCore",
|
||||
"leveldb",
|
||||
.product(name: "nanopb", package: "nanopb"),
|
||||
.product(name: "abseil", package: "abseil-cpp-SwiftPM"),
|
||||
.product(name: "gRPC-cpp", package: "grpc-ios"),
|
||||
.product(name: "abseil", package: "abseil-cpp-SwiftPM",
|
||||
condition: .when(traits: ["Firestore"])),
|
||||
.product(name: "gRPC-cpp", package: "grpc-ios",
|
||||
condition: .when(traits: ["Firestore"])),
|
||||
],
|
||||
path: "Firestore",
|
||||
exclude: [
|
||||
@@ -1600,17 +1642,20 @@ func firestoreTargets() -> [Target] {
|
||||
dependencies: [
|
||||
.target(
|
||||
name: "FirebaseFirestoreInternalWrapper",
|
||||
condition: .when(platforms: [.iOS, .macCatalyst, .tvOS, .macOS])
|
||||
condition: .when(platforms: [.iOS, .macCatalyst, .tvOS, .macOS],
|
||||
traits: ["Firestore"])
|
||||
),
|
||||
.product(
|
||||
name: "abseil",
|
||||
package: "abseil-cpp-binary",
|
||||
condition: .when(platforms: [.iOS, .macCatalyst, .tvOS, .macOS])
|
||||
condition: .when(platforms: [.iOS, .macCatalyst, .tvOS, .macOS],
|
||||
traits: ["Firestore"])
|
||||
),
|
||||
.product(
|
||||
name: "gRPC-C++",
|
||||
package: "grpc-binary",
|
||||
condition: .when(platforms: [.iOS, .macCatalyst, .tvOS, .macOS])
|
||||
condition: .when(platforms: [.iOS, .macCatalyst, .tvOS, .macOS],
|
||||
traits: ["Firestore"])
|
||||
),
|
||||
.product(name: "nanopb", package: "nanopb"),
|
||||
"FirebaseAppCheckInterop",
|
||||
@@ -1635,7 +1680,8 @@ func firestoreTargets() -> [Target] {
|
||||
name: "FirebaseFirestoreInternalWrapper",
|
||||
dependencies: [.target(
|
||||
name: "FirebaseFirestoreInternal",
|
||||
condition: .when(platforms: [.iOS, .macCatalyst, .tvOS, .macOS])
|
||||
condition: .when(platforms: [.iOS, .macCatalyst, .tvOS, .macOS],
|
||||
traits: ["Firestore"])
|
||||
)],
|
||||
path: "FirebaseFirestoreInternal",
|
||||
publicHeadersPath: "."
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
#warning "Firebase Firestore does not support watchOS"
|
||||
#endif
|
||||
|
||||
#if !defined(FIRESTORE_TRAIT_ENABLED)
|
||||
#error "FirebaseFirestore was included in your project dependencies, but the \
|
||||
'Firestore' SwiftPM package trait is disabled. To use Firestore, please \
|
||||
enable the 'Firestore' trait (or default traits) in your Package.swift \
|
||||
or in the Package Dependencies tab of your Xcode project."
|
||||
#endif // !defined(FIRESTORE_TRAIT_ENABLED)
|
||||
|
||||
#if TARGET_OS_VISION && FIREBASE_BINARY_FIRESTORE
|
||||
#error "Firebase Firestore's binary SPM distribution does not support \
|
||||
visionOS. To enable the source distribution, quit Xcode and open the desired \
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
#import "FirebaseCore/FirebaseCore.h"
|
||||
#import "FirebaseCrashlytics/FirebaseCrashlytics.h"
|
||||
#import "FirebaseDatabase/FirebaseDatabase.h"
|
||||
#if defined(FIRESTORE_TRAIT_ENABLED)
|
||||
#import "FirebaseFirestore/FirebaseFirestore.h"
|
||||
#endif // defined(FIRESTORE_TRAIT_ENABLED)
|
||||
#import "FirebaseInstallations/FirebaseInstallations.h"
|
||||
#import "FirebaseMessaging/FirebaseMessaging.h"
|
||||
#if (TARGET_OS_IOS && !TARGET_OS_MACCATALYST) || TARGET_OS_TV
|
||||
@@ -39,7 +41,9 @@
|
||||
#import <FirebaseCore/FirebaseCore.h>
|
||||
#import <FirebaseCrashlytics/FirebaseCrashlytics.h>
|
||||
#import <FirebaseDatabase/FirebaseDatabase.h>
|
||||
#if defined(FIRESTORE_TRAIT_ENABLED)
|
||||
#import <FirebaseFirestore/FirebaseFirestore.h>
|
||||
#endif // defined(FIRESTORE_TRAIT_ENABLED)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
#import <FirebaseInAppMessaging/FirebaseInAppMessaging.h>
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
@import FirebaseCrashlytics;
|
||||
@import FirebaseCore;
|
||||
@import FirebaseDatabase;
|
||||
#if defined(FIRESTORE_TRAIT_ENABLED)
|
||||
@import FirebaseFirestore;
|
||||
#endif // defined(FIRESTORE_TRAIT_ENABLED)
|
||||
@import FirebaseFunctions;
|
||||
@import FirebaseInstallations;
|
||||
@import FirebaseMessaging;
|
||||
|
||||
@@ -23,7 +23,9 @@ import Foundation
|
||||
#endif
|
||||
import FirebaseCrashlytics
|
||||
import FirebaseDatabase
|
||||
import FirebaseFirestore
|
||||
#if Firestore // Gated by the "Firestore" SwiftPM package trait.
|
||||
import FirebaseFirestore
|
||||
#endif // Firestore
|
||||
import FirebaseFunctions
|
||||
import FirebaseInstallations
|
||||
import FirebaseMessaging
|
||||
|
||||
Reference in new issue
Block a user