FireForNet.Firebase.Firestore 1.0.1-preview.22

Prefix Reserved
This is a prerelease version of FireForNet.Firebase.Firestore.
dotnet add package FireForNet.Firebase.Firestore --version 1.0.1-preview.22
                    
NuGet\Install-Package FireForNet.Firebase.Firestore -Version 1.0.1-preview.22
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FireForNet.Firebase.Firestore" Version="1.0.1-preview.22" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FireForNet.Firebase.Firestore" Version="1.0.1-preview.22" />
                    
Directory.Packages.props
<PackageReference Include="FireForNet.Firebase.Firestore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FireForNet.Firebase.Firestore --version 1.0.1-preview.22
                    
#r "nuget: FireForNet.Firebase.Firestore, 1.0.1-preview.22"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FireForNet.Firebase.Firestore@1.0.1-preview.22
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FireForNet.Firebase.Firestore&version=1.0.1-preview.22&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=FireForNet.Firebase.Firestore&version=1.0.1-preview.22&prerelease
                    
Install as a Cake Tool

FireForNet.Firebase.Firestore

Cloud Firestore for the FireForNet Firebase Client SDK for .NET.

About FireForNet

FireForNet is a platform-agnostic, .NET-native Firebase Client SDK developed as part of the Circuids ecosystem. It provides a consistent Firebase client development experience across .NET application environments, while allowing platform-specific implementations where Firebase requires them.

About This Package

This package provides the Firestore SDK for FireForNet:

  • Typed document and collection references
  • Queries, snapshots, and listeners
  • Batched writes and transactions
  • Bundles
  • Local store contracts, with platform-agnostic SQLite persistence available as a companion package
  • The default WebChannel-capable transport, with a native gRPC (HTTP/2) transport available as an add-on package

Installation

dotnet add package FireForNet.Firebase.Firestore

Targets net10.0. References FireForNet.Firebase.Core transitively.

Setup

builder.Services.AddFirestore();

Platform and transport packages extend the returned FirestoreBuilder:

builder.Services.AddFirestore().UseBlazor(...);   // Blazor (all hosting models)
builder.Services.AddFirestore().UseBrowser();     // framework-independent WASM
builder.Services.AddFirestore().UseMaui();        // .NET MAUI
builder.Services.AddFirestore().UseWindows();     // Windows desktop
builder.Services.AddFirestore().UseAndroid(...);  // native (non-MAUI) Android
builder.Services.AddFirestore().UseApple(...);    // iOS / macOS / Mac Catalyst
builder.Services.AddFirestore().UseSqlite(databasePath); // SQLite persistence
builder.Services.AddFirestore().UseNativeGrpc();  // native gRPC transport add-on

Usage

Resolve IFirestore from DI:

public class ChatRepository(IFirestore firestore)
{
    private readonly ICollectionReference<ChatMessage> _rooms =
        firestore.Collection<ChatMessage>("rooms");

    public async Task<string> AddMessageAsync(string roomId, ChatMessage message)
    {
        var doc = await _rooms.Document(roomId).Collection<ChatMessage>("messages")
            .AddAsync(message);
        return doc.Id;
    }

    public async Task<IReadOnlyList<ChatMessage>> GetRecentAsync(string roomId)
    {
        var snapshot = await _rooms
            .WhereEqualTo("roomId", roomId)
            .OrderByDescending("sentAt")
            .Limit(50)
            .GetAsync();
        return snapshot.Documents.Select(d => d.Data).ToList();
    }

    public async Task ListenAsync(string roomId)
    {
        var doc = _rooms.Document(roomId);
        var listener = await doc.OnSnapshotAsync(snapshot =>
        {
            var data = snapshot.Data;
            // react to updates
        });
        // stop listening when done:
        await listener.DisposeAsync();
    }
}

IFirestore also exposes Document<T>(path) for single-document access, RunTransactionAsync<T> for transactions, and batched writes via IWriteBatch.

Package Purpose
FireForNet.Firebase.Firestore.Blazor Blazor integration (WebAssembly, Server, Hybrid, Auto)
FireForNet.Firebase.Firestore.Browser Framework-independent WASM integration
FireForNet.Firebase.Firestore.Maui .NET MAUI integration
FireForNet.Firebase.Firestore.Windows Windows desktop integration
FireForNet.Firebase.Firestore.Android Native (non-MAUI) Android integration
FireForNet.Firebase.Firestore.Apple Apple native integration (iOS, macOS, Mac Catalyst)
FireForNet.Firebase.Firestore.Sqlite Platform-agnostic SQLite persistence
FireForNet.Firebase.Firestore.Grpc Native gRPC (HTTP/2) transport add-on

Documentation

Comprehensive FireForNet documentation is being prepared for the Release Candidate stage.

Project Status

FireForNet is currently available as a Preview release and is approaching its Release Candidate milestone. APIs, package structure, and implementation details may continue to evolve before RC and GA.

The RC milestone will be followed by an extensive cross-platform validation and testing phase before the first GA release.

All FireForNet packages are part of a coordinated release train and share the same version number.

Source Availability

FireForNet is currently being developed in a private source repository during the Preview development phase. The source will be made publicly available as the project approaches its open-source phase, with the public repository established from the appropriate release milestone.

Until then, NuGet Preview packages provide the public distribution channel for evaluating and using FireForNet.

License

This package is licensed under the Apache-2.0 license.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (8)

Showing the top 5 NuGet packages that depend on FireForNet.Firebase.Firestore:

Package Downloads
FireForNet.Firebase.Firestore.Browser

Package Description

FireForNet.Firebase.Firestore.Blazor

Package Description

FireForNet.Firebase.Firestore.Sqlite

Package Description

FireForNet.Firebase.Firestore.Grpc

Native gRPC (HTTP/2) transport addon for FireForNet Firestore SDK

FireForNet.Firebase.Firestore.Windows

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1-preview.22 82 9/27/2026
1.0.1-preview.21 83 9/22/2026
1.0.1-preview.20 83 9/18/2026
1.0.1-preview.19 80 9/12/2026
1.0.1-preview.18 123 8/24/2026
1.0.1-preview.17 101 8/9/2026
1.0.1-preview.16 80 8/9/2026
1.0.1-preview.15 84 8/8/2026
1.0.1-preview.14 88 8/8/2026
1.0.1-preview.13 101 7/23/2026
1.0.1-preview.12 128 7/9/2026
1.0.1-preview.11 105 6/29/2026
1.0.1-preview.10 91 6/25/2026
1.0.1-preview.9 100 6/24/2026
1.0.1-preview.8 94 6/23/2026
1.0.1-preview.7 84 6/9/2026
1.0.1-preview.6 90 6/8/2026
1.0.1-preview.5 98 6/8/2026
1.0.1-preview.4 101 6/8/2026
1.0.1-preview.3 82 6/8/2026
Loading failed

v1.0.1-preview.22
- BREAKING: MutationKind, FieldTransformKind, MutationBatchState, and TargetPurposeMessage are readonly record struct wire types with canonical all-lowercase strings ("set", "servertimestamp", "queued", "listen", ...). Enum-only usage (switch patterns, (int) casts) no longer compiles; parsing accepts any casing.
- BREAKING: mutation-batch state persists as canonical strings instead of integer ordinals; cross-tab WatchStreamMessage.targetMismatches values are canonical strings instead of integers.
- BREAKING: dictionary writes, query/cursor/pipeline literals, and object-slot values derive their wire form from scope System.Text.Json behavior instead of ToString() - typed and direct write paths are now coherent (Enum.ToString() never reaches the wire).
- Cross-tab online-state broadcasts use canonical lowercase strings ("online", "offline", "unknown"); reads remain case-insensitive.
- BREAKING: typed writes store explicit nulls - a null model property becomes a null field (JS setDoc/FlutterFire parity). Declare [JsonIgnore(Condition = WhenWritingNull)] per property to keep omitting it.
- Fixed: objects containing byte[]/Timestamp/GeoPoint resolve identically on typed-write and literal paths (__ffnType envelopes are honored in both; previously literals produced map values). FirestoreBlob fields now write proper bytes values (type-owned codec) instead of map values.
- Timestamp/GeoPoint codecs are type-owned only - their redundant scope registrations were removed (OQ1); the bytes envelope codec stays registered because byte[] cannot declare its own converter.

v1.0.1-preview.21
- No functional changes; synchronized with the framework-free MAUI integration sweep.

v1.0.1-preview.20
- Synchronized package version with the preview.20 release.

v1.0.1-preview.19
- Synchronized package version with the preview.19 release.

v1.0.1-preview.18
- Synchronized package version with the preview.18 release.

v1.0.1-preview.17
- Synchronized package version with the preview.17 release.

v1.0.1-preview.16
- Synchronized package version with the preview.16 release.

v1.0.1-preview.15
- Synchronized package version with the preview.15 release.

v1.0.1-preview.14
- Synchronized package version with the preview.14 release.

v1.0.1-preview.13
- Added offline-first optimistic writes (opt-in via FirestoreBuilder.OptimisticWrites). Writes apply locally immediately, queue in a per-user mutation queue, and flush to the server over a persistent bidirectional Write stream with resumable stream tokens. Listeners reflect pending writes via merged-view computation (server snapshot + overlays). WaitForPendingWritesAsync resolves when all queued mutations are acknowledged.
- Added ILocalStoreMutationQueue and ILocalStoreOverlayCache public capability contracts (detected by interface presence) for persisting pending mutation batches and per-document overlays.
- Added OptimisticWriteCoordinator, WritePipeline, PersistentWriteStream, and LimboResolver internal components implementing the decoupled offline-first write model without a monolithic SyncEngine.
- Added field transform overlay semantics: ServerTimestamp, Increment, ArrayUnion, ArrayRemove, field Delete, and Vector apply optimistically to the local view and are never double-applied after reconnection.
- Added Transaction.GetAsync merged-view reads when optimistic writes are enabled (transactions see the user's own pending writes).
- Eliminated the proto-to-JSON-to-Dictionary-to-T round-trip on the server read path: ProtoValueJsonWriter bridges proto MapField<string,Value> directly to Utf8JsonWriter tokens for System.Text.Json, with no intermediate Dictionary or string allocation.
- Eliminated the T-to-string-to-Dictionary-to-proto round-trip on the write path: ProtoValueJsonReader bridges Utf8JsonReader tokens directly to proto MapField<string,Value>, with no intermediate string allocation.
- Added ObjectJsonConverter so object? properties receive CLR primitives (string, long, double, bool, List<object?>, Dictionary<string,object?>) instead of JsonElement on both read and write round-trips.
- Fixed fire-and-forget exception swallowing and ordering violation in the Write stream response path: PersistentWriteStream events changed from Action to Func<...,Task> and are now awaited by the receive loop, preserving ordered ack processing and propagating exceptions.

v1.0.1-preview.12
- Fixed ObjectDisposedException on SemaphoreSlim.Release() during network disable. A race between DisableNetworkAsync and the fire-and-forget watch-stream receive loop allowed the stream to be restarted on a disposed PersistentListenStream after _gate had been disposed. RemoteStore now atomically guards ShouldStartWatchStream with _networkEnabled, and the PersistentListenStream start path detects disposed state before acquiring the gate.
- Fixed UnobservedTaskException caused by OperationCanceledException escaping the WebChannel receive loop during concurrent disposal. The receive loop now catches JSException wrapping OperationCanceledException (surfaced by .NET 10 WASM fetch abort), and HandleStreamErrorAsync is defensive against ObjectDisposedException when CloseInternalAsync races with DisposeAsync.

v1.0.1-preview.11
- Synchronized package version with the preview.11 release.

v1.0.1-preview.10
- Fixed "Cursor has too many values" (HTTP 400 INVALID_ARGUMENT) error on server queries using snapshot cursors (StartAt/StartAfter/EndAt/EndBefore with IDocumentSnapshot). Query.BuildStructuredQuery now emits normalized order-bys (explicit + implicit inequality fields + __name__ last) and serializes __name__ cursor values as ReferenceValue instead of plain string.
- Added QueryNormalizer helper centralizing the normalized order-by algorithm shared by server and local cache query paths.
- Added field-cursor validation: StartAt/StartAfter/EndAt/EndBefore(params object[]) now throw FirestoreException(InvalidArgument) when values exceed the explicit orderBy count.
- Refactored LocalQueryEvaluator to reuse QueryNormalizer, removing duplicated normalization logic.

v1.0.1-preview.9
- Fixed Timestamp to register a default JsonConverter via [JsonConverter(typeof(TimestampJsonConverter))], so System.Text.Json serialization works without an explicit user-supplied converter.
- Fixed TimestampJsonConverter.Read to handle both Firestore wire-format fields (_seconds/_nanoseconds) and the FireForNet serialized format (seconds/nanoseconds), ensuring round-trip deserialization from emulator and production responses.

v1.0.1-preview.8
- Added FirestoreErrorCode.LocalCacheFull (104) for client-side persistence cache-at-capacity errors.
- FirestoreException now extends FirebaseCoreException<FirestoreErrorCode>; MapToCoreCode deleted.
- ExceptionHelper.MapToFirestoreException is now one-way only (no reverse round-trip).

v1.0.1-preview.7
- Synchronized package version with the preview.7 release.

v1.0.1-preview.6
- Synchronized package version with the preview.6 release.

v1.0.1-preview.5
- Synchronized package version with the preview.5 release.

v1.0.1-preview.4
- Synchronized package version with the preview.4 release.

v1.0.1-preview.3
- Synchronized package version with the preview.3 release.

v1.0.1-preview.2
- Synchronized package version with the preview.2 release.

v1.0.1-preview.1
- Synchronized package version with the preview10 release.

v1.0.0-preview9
- Synchronized package version with the preview9 browser-interop-migration release.

v1.0.0-preview8
- Promoted FieldIndexValueEncoder and FieldPathHelper to public Firestore API so persistence backends share identical field-index encoding without internal-visibility coupling.
- Renamed ILocalStoreIndexManagement.DeleteIndexAsync to RemoveIndexAsync.
- Firestore now throws FirestoreErrorCode.FailedPrecondition when persistence is enabled with a cache size limit but the active local store does not implement ILocalStoreCacheManagement.
- Hardened InMemoryLocalStore multi-document ApplyChangesAsync atomicity under a single lock so concurrent reads never observe a partially applied batch.

v1.0.0-preview7
- Reworked local cache architecture with plan-based candidate retrieval through LocalQueryPlan, LocalQueryExecutor, and LocalQueryPlanner.
- Replaced broad ILocalStore.QueryAsync contract with QueryCandidatesAsync so stores return safe candidate supersets and Core Firestore remains the semantic authority.
- Added SQLite equality pushdown for supported scalar fields as a proven candidate-reduction path with mandatory final LocalQueryEvaluator execution.
- Collection path, collection group, and document path narrowing with broad-scan fallback across all stores.

v1.0.0-preview6
- Improved local cache query evaluation for cursor bounds, snapshot cursor document-name tie-breakers, and special numeric values.

v1.0.0-preview5
- Fixed Blazor WebAssembly startup crash when IFirestore is resolved early by flowing Google.Protobuf as a runtime package dependency while keeping its compile assets private to Firestore.

v1.0.0-preview4
- Synchronized package version with the preview4 release.

v1.0.0-preview3
- Synchronized package version with the preview3 release.

v1.0.0-preview2
- Initial v1.0.0-preview2 package.