-
Notifications
You must be signed in to change notification settings - Fork 1.7k
docs(firestore): Add docs on Firestore x SPM integration #15387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ncooke3
wants to merge
9
commits into
main
Choose a base branch
from
nc/fst-docs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+199
−0
Open
Changes from 8 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
3a01415
docs(firestore): Add docs on Firestore x SPM integration
ncooke3 3b9d49c
Review comments
ncooke3 429d571
Add a more detail on where BoringSSL fits in
ncooke3 c4e650d
more polishing
ncooke3 5cdfd10
trim
ncooke3 6e2a62c
more polish
ncooke3 4175689
final review
ncooke3 39dad0a
more polish yet
ncooke3 26b82c1
Update docs/FirestoreSPM.md
ncooke3 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
# Firestore Swift Package Manager Target Hierarchy | ||
|
||
This document outlines the hierarchy of the Firestore-related targets in the | ||
`Package.swift` manifest. The setup is designed to support three different | ||
build options for Firestore: from a pre-compiled binary (the default), from | ||
source (via the `FIREBASE_SOURCE_FIRESTORE` environment variable), or from a | ||
local binary for CI purposes (via the `FIREBASECI_USE_LOCAL_FIRESTORE_ZIP` | ||
environment variable). | ||
|
||
--- | ||
|
||
## 1. Binary-based build (Default) | ||
|
||
When the `FIREBASE_SOURCE_FIRESTORE` environment variable is **not** set, SPM | ||
will use pre-compiled binaries for Firestore and its heavy dependencies. This | ||
is the default and recommended approach for most users. | ||
|
||
### Dependency hierarchy | ||
|
||
The dependency tree for a binary-based build is as follows: | ||
|
||
``` | ||
FirebaseFirestore (Library Product) | ||
└── FirebaseFirestoreTarget (Wrapper Target) | ||
└── FirebaseFirestore (Swift Target) | ||
├── FirebaseAppCheckInterop | ||
├── FirebaseCore | ||
├── FirebaseCoreExtension | ||
├── FirebaseSharedSwift | ||
├── leveldb | ||
├── nanopb | ||
├── abseil (binary) (from https://github.com/google/abseil-cpp-binary.git) | ||
├── gRPC-C++ (binary) (from https://github.com/google/grpc-binary.git, contains BoringSSL-GRPC target) | ||
└── FirebaseFirestoreInternalWrapper (Wrapper Target) | ||
└── FirebaseFirestoreInternal (Binary Target) | ||
``` | ||
|
||
### Target breakdown | ||
|
||
* **`FirebaseFirestore`**: The Swift target containing the public API. In this | ||
configuration, it depends on the binary versions of abseil and gRPC, as | ||
well as the `FirebaseFirestoreInternalWrapper`. | ||
* **`FirebaseFirestoreInternalWrapper`**: A thin wrapper target that exists to | ||
expose the headers from the underlying binary target. | ||
* **`FirebaseFirestoreInternal`**: This is a `binaryTarget` that downloads and | ||
links the pre-compiled `FirebaseFirestoreInternal.xcframework`. This | ||
framework contains the compiled C++ core of Firestore. | ||
|
||
--- | ||
|
||
## 2. Source-based build | ||
|
||
When the `FIREBASE_SOURCE_FIRESTORE` environment variable is set, Firestore and | ||
its dependencies (like abseil and gRPC) are compiled from source. | ||
|
||
### How to build Firestore from source | ||
|
||
To build Firestore from source, set the `FIREBASE_SOURCE_FIRESTORE` environment | ||
variable before building the project. | ||
|
||
#### Building with Xcode | ||
|
||
A direct method for building within Xcode is to pass the environment variable | ||
upon opening it from the command line. This approach scopes the variable to the | ||
ncooke3 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
Xcode instance. To enable an env var within Xcode, first quit any running Xcode | ||
instance, and then open the project from the command line: | ||
|
||
```console | ||
open --env FIREBASE_SOURCE_FIRESTORE Package.swift | ||
``` | ||
|
||
To unset the env var, quit the running Xcode instance. If you need to pass | ||
multiple variables, repeat the `--env` argument for each: | ||
```console | ||
open --env FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT \ | ||
--env FIREBASE_SOURCE_FIRESTORE Package.swift | ||
``` | ||
|
||
#### Command-line builds | ||
|
||
For command-line builds using `xcodebuild` or `swift build`, the recommended | ||
approach is to prefix the build command with the environment variable. This sets | ||
the variable only for that specific command, avoiding unintended side effects. | ||
|
||
```bash | ||
FIREBASE_SOURCE_FIRESTORE=1 xcodebuild -scheme FirebaseFirestore \ | ||
-destination 'generic/platform=iOS' | ||
``` | ||
|
||
Alternatively, if you plan to run multiple commands that require the variable | ||
to be set, you can `export` it. This will apply the variable to all subsequent | ||
commands in that terminal session. | ||
|
||
```bash | ||
export FIREBASE_SOURCE_FIRESTORE=1 | ||
xcodebuild -scheme FirebaseFirestore -destination 'generic/platform=iOS' | ||
# Any other commands here will also have the variable set | ||
``` | ||
|
||
Once the project is built with the variable set, SPM will clone and build | ||
Firestore and its C++ dependencies (like abseil and gRPC) from source. | ||
|
||
### Dependency hierarchy | ||
|
||
The dependency tree for a source-based build looks like this: | ||
|
||
``` | ||
FirebaseFirestore (Library Product) | ||
└── FirebaseFirestoreTarget (Wrapper Target) | ||
└── FirebaseFirestore (Swift Target) | ||
├── FirebaseCore | ||
├── FirebaseCoreExtension | ||
├── FirebaseSharedSwift | ||
└── FirebaseFirestoreInternalWrapper (C++ Target) | ||
├── FirebaseAppCheckInterop | ||
├── FirebaseCore | ||
├── leveldb | ||
├── nanopb | ||
├── abseil (source) (from https://github.com/firebase/abseil-cpp-SwiftPM.git) | ||
└── gRPC-cpp (source) (from https://github.com/grpc/grpc-ios.git) | ||
└── BoringSSL (source) (from https://github.com/firebase/boringSSL-SwiftPM.git) | ||
``` | ||
|
||
### Target breakdown | ||
|
||
* **`FirebaseFirestore`**: The main Swift target containing the public Swift | ||
API for Firestore. It acts as a bridge to the underlying C++ | ||
implementation. | ||
* **`FirebaseFirestoreInternalWrapper`**: This target compiles the core C++ | ||
source code of Firestore. It depends on other low-level libraries and C++ | ||
dependencies, which are also built from source. | ||
|
||
--- | ||
|
||
## 3. Local binary build (CI only) | ||
|
||
A third, less common build option is available for CI environments. When the | ||
`FIREBASECI_USE_LOCAL_FIRESTORE_ZIP` environment variable is set, the build | ||
system will use a local `FirebaseFirestoreInternal.xcframework` instead of | ||
downloading the pre-compiled binary. This option assumes the xcframework is | ||
located at the root of the repository. | ||
|
||
This option is primarily used by internal scripts, such as | ||
`scripts/check_firestore_symbols.sh`, to perform validation against a locally | ||
built version of the Firestore binary. It is not intended for general consumer | ||
use. | ||
|
||
--- | ||
|
||
## Core target explanations | ||
|
||
### `FirebaseFirestore` (Library product) | ||
|
||
The main entry point for integrating Firestore via SPM is the | ||
`FirebaseFirestore` library product. | ||
|
||
```swift | ||
.library( | ||
name: "FirebaseFirestore", | ||
targets: ["FirebaseFirestoreTarget"]) | ||
``` | ||
|
||
This product points to a wrapper target, `FirebaseFirestoreTarget`, which then | ||
depends on the appropriate Firestore targets based on the chosen build option. | ||
|
||
### `FirebaseFirestoreTarget` (Wrapper target) | ||
|
||
The `FirebaseFirestoreTarget` is a thin wrapper that exists to work around a | ||
limitation in SPM where a single target cannot conditionally depend on | ||
different sets of targets (source vs. binary). | ||
|
||
By having clients depend on the wrapper, the `Package.swift` can internally | ||
manage the complexity of switching between source and binary builds. This | ||
provides a stable entry point for all clients and avoids pushing conditional | ||
logic into their own package manifests. | ||
|
||
--- | ||
|
||
## Test targets | ||
|
||
The testing infrastructure for Firestore in SPM is designed to be independent | ||
of the build choice (source vs. binary). | ||
|
||
* **`FirebaseFirestoreTestingSupport`**: This is a library target, not a test | ||
target. It provides public testing utilities that consumers can use to | ||
write unit tests for their Firestore-dependent code. It has a dependency on | ||
`FirebaseFirestoreTarget`, which means it will link against whichever | ||
version of Firestore (source or binary) is being used in the build. | ||
|
||
* **`FirestoreTestingSupportTests`**: This is a test target that contains the | ||
unit tests for the `FirebaseFirestoreTestingSupport` library itself. Its | ||
purpose is to validate the testing utilities. | ||
|
||
Because both of these targets depend on the `FirebaseFirestoreTarget` wrapper, | ||
they seamlessly adapt to either the source-based or binary-based build path | ||
without any conditional logic. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.