This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
FirebaseAPI is a server-side Swift package that enables Firestore integration on platforms where the official Firebase SDK cannot run.
Why this library exists:
- The official Firebase SDK is designed for iOS/Android/Web clients and does not support server-side Swift environments (Linux, Vapor, Hummingbird, etc.)
- Server-side Swift applications need direct Firestore access without depending on client SDKs
- Existing solutions require Node.js or other runtimes, preventing pure Swift backend implementations
What this library provides:
- Native Swift interface to Google Cloud Firestore using gRPC
- Full compatibility with server-side Swift frameworks (Vapor, Hummingbird)
- Cross-platform support including Linux servers
- API design that closely mirrors official Firebase SDKs for familiarity
- Built entirely on Swift concurrency (async/await) and gRPC-Swift 2.x
Primary use cases:
- Backend services written in Swift (Vapor, Hummingbird)
- Command-line tools and scripts
- macOS server applications
- Linux-based cloud deployments
- Any Swift environment where official Firebase SDK is unavailable
The library uses a hierarchical reference model similar to Firebase SDKs, but the entry point is server-side Admin:
FirestoreAdmin: Root Admin facade that owns runtime dispatch and server-side lifecycleCollectionReference: Represents a Firestore collection pathDocumentReference: Represents a specific document pathQuery: Represents a query with filters, ordering, and limitsCollectionGroup: Queries across all collections with the same ID
Public API code, protobuf request compilation, and concrete grpc-swift transport execution are separate responsibilities:
Sources/FirestoreCore: Protobuf-free model, query, reference, snapshot, value, source, listen, aggregation, vector, and error typesSources/FirestoreAdmin: Server-side Admin workflow facade and narrow dependency-injection protocolsSources/FirestoreRPC: Native Firestore request compilers, response mappers, query validation, and Listen reducersSources/FirestorePipelineRPC: Firestore Pipeline request compiler and ExecutePipeline response mapperSources/FirestoreGRPCTransport: Concrete grpc-swift transport lifecycle, authorization metadata, retry execution, and generated client callsSources/FirestoreProtobuf/Proto: Generated protobuf messagesSources/FirestoreGRPCStubs/Proto: Generated gRPC stubs
This separation keeps public Admin workflow code free of protobuf, generated gRPC, and concrete transport details.
The library provides custom FirestoreEncoder and FirestoreDecoder in Sources/FirestoreCodable/Cadable/:
- Handles Firestore-specific types:
Timestamp,GeoPoint,DocumentReference - Supports special property wrappers:
@DocumentID,@ExplicitNull,@ReferencePath,@ServerTimestamp - Converts between Swift types and Firestore protocol buffer values
Queries use a public Filter facade backed by package-internal QueryPredicate planning state:
- Predicates are accumulated in an array and composed into composite filters
- Supports field filters, unary filters, and composite filters (AND/OR)
- Special handling for document ID queries vs field queries
QueryCompilerconverts query state into FirestoreStructuredQueryprotobuf requests
FirestoreAdminTransaction: Atomic read-then-write operations with transaction-level retryFirestoreAdminWriteBatch: Atomic Commit-backed batched writesFirestoreAdminBulkWriter: Non-atomic BatchWrite-backed bulk writes with per-write status results
# Build the package
swift build --configuration debug
# Run all tests
perl -e 'alarm shift; exec @ARGV' 300 xcodebuild -quiet -scheme FirebaseAPI-Package -destination 'platform=macOS' test
# Build specific configuration
swift build -c release
# Run specific test
perl -e 'alarm shift; exec @ARGV' 120 xcodebuild -quiet -scheme FirebaseAPI-Package -destination 'platform=macOS' test -only-testing:FirebaseAPITests/FirestoreEncoderTestsThe project uses a googleapis submodule (goolgeapis/) to generate Firestore API bindings:
# Generate proto files (run from project root)
./scripts/generate-firestore-protos.shGenerated protobuf files are in Sources/FirestoreProtobuf/Proto/; generated gRPC stubs are in Sources/FirestoreGRPCStubs/Proto/. They should not be manually edited.
Most tests run without external credentials. Firestore emulator integration uses firebase emulators:exec, and production Firestore smoke tests are opt-in through environment variables:
FIRESTORE_LIVE_SMOKE=1FIRESTORE_LIVE_PROJECT_IDGOOGLE_APPLICATION_CREDENTIALSor another supported Application Default Credentials source
All Firestore operations require OAuth2 access tokens:
- Implement
AccessTokenProviderprotocol to supply tokens - Prefer
FirestoreAdmin(credentials:),FirestoreAdmin.applicationDefault(), orFirestoreAdmin.applicationDefaultResolvingProjectID() - Tokens are passed through gRPC metadata by
FirestoreGRPCTransport
FirestoreTransactionBackoff: Retry logic for transactions (max attempts configurable)FirestoreRetryHandler: Actor-based retry with configurable strategies (exponential, linear, custom)FirestoreError: Custom error types for Firestore-specific failures
All paths are normalized using .normalized extension on String to handle trailing slashes and empty components. Reference types validate path structure (collections have odd segments, documents have even segments).
@DocumentID<String>: Auto-populated with document ID during decoding, excluded from encoding unless explicitly set@ExplicitNull: Distinguishes between "field not set" and "field set to null"@ReferencePath: Encodes/decodes DocumentReference paths as strings
- Database Validation: All write operations check that
document.database == firestore.databasebefore proceeding - Path Validation: Collection IDs and document IDs are validated for empty strings and invalid characters (no "/" allowed)
- Transaction Reads Before Writes: Transactions enforce read-before-write (throws
FirestoreError.readAfterWriteError) - Concurrency Safety: Uses Swift concurrency and package-internal runtime seams; public API code should not depend on concrete grpc-swift transport types
The library now fully supports real-time listeners using grpc-swift-2's bidirectional streaming API.
Available APIs:
DocumentReference.addSnapshotListener()- Real-time document listenersQuery.addSnapshotListener()- Real-time query listeners
Implementation details:
FirestoreListenStreamExecutorowns concrete streaming gRPC request constructionListenStreamCoordinatorowns target add/remove sequencing, retry, resume token, and full-resync control- Returns
AsyncThrowingStreamfor easy consumption withfor try await
Example usage:
// Document listener
let docRef = firestore.collection("users").document("user123")
let stream = try await docRef.addSnapshotListener()
for try await snapshot in stream {
print("Document updated: \(snapshot.data())")
}
// Query listener
let query = firestore.collection("users").whereField("age", isGreaterThanOrEqualTo: 18)
let stream = try await query.addSnapshotListener()
for try await snapshot in stream {
print("Query results: \(snapshot.documents.count) documents")
}Implementation locations:
Sources/FirestoreRPC/Listen/ListenStreamCoordinator.swift- Listen reconnect and resume-token coordinationSources/FirestoreRPC/Listen/DocumentListenState.swift- Document listen response reductionSources/FirestoreRPC/Listen/QueryListenState.swift- Query listen response reductionSources/FirestoreGRPCTransport/FirestoreListenStreamExecutor.swift- Streaming gRPC request execution
Note on testing:
- Real-time listeners can be tested with the Firestore emulator
- Use task cancellation to stop listening:
task.cancel()
Sources/FirestoreAPI/
└── Compatibility re-export files
Sources/FirestoreAdmin/ Server-side Admin facade
Sources/FirestoreAdminServer/ Preferred server-side product re-exports
Sources/FirestoreCore/ Public model/query/reference/snapshot types
Sources/FirestoreCodable/ FirestoreEncoder, FirestoreDecoder, property wrappers
Sources/FirestoreRPC/ Native Firestore compilers and response mappers
Sources/FirestorePipelineRPC/ Pipeline compiler and response mapper
Sources/FirestoreGRPCTransport/ Concrete grpc-swift transport execution
Sources/FirestoreProtobuf/Proto/ Generated protobuf files
Sources/FirestoreGRPCStubs/Proto/ Generated gRPC stub files
- iOS 18+
- macOS 15+
- watchOS 11+
- tvOS 18+
- visionOS 2+
- Uses Swift 6.2+ (see Package.swift)