---
title: "What's New in Capacitor Firebase 8.3.0"
description: Capacitor Firebase 8.3.0 adds new Firestore data types, filtered count queries, a serverTimestamps listener option, and Remote Config setDefaults and getAll.
date:
  created: 2026-06-04
  updated: 2026-06-04
authors:
  - robingenz
categories:
  - Firebase
---

# What's New in Capacitor Firebase 8.3.0

Capacitor Firebase 8.3.0 is out, and the work is split across two plugins. Cloud Firestore gains support for data types it used to mangle — `DocumentReference`, `Bytes`, and `NaN`/`Infinity` — along with filtered count queries and a `serverTimestamps` option on snapshot listeners. Remote Config picks up `setDefaults(...)`, `getAll()`, and a `source` field that finally works on the web.

<!-- more -->

<div class="capawesome-z29o10a">
  <a href="https://capawesome.io/" target="_blank">
    <img alt="Build and deploy your Capacitor app with Capawesome Cloud" src="https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
  </a>
</div>

## At a Glance

Here's the full list of changes in this release:

| Change                                                    | Plugin              | Platforms           | PR                                                                                       |
| --------------------------------------------------------- | ------------------- | ------------------- | ---------------------------------------------------------------------------------------- |
| `DocumentReference`, `Bytes`, `NaN`/`Infinity` data types | Firestore           | Web + iOS + Android | [#991](https://github.com/capawesome-team/capacitor-firebase/pull/991){:target="_blank"} |
| Queries in `getCountFromServer(...)`                      | Firestore           | Web + iOS + Android | [#988](https://github.com/capawesome-team/capacitor-firebase/pull/988){:target="_blank"} |
| `serverTimestamps` option on snapshot listeners           | Firestore           | Web + iOS + Android | [#993](https://github.com/capawesome-team/capacitor-firebase/pull/993){:target="_blank"} |
| `limitToLast` constraint fixed on Android                 | Firestore           | Android             | [#992](https://github.com/capawesome-team/capacitor-firebase/pull/992){:target="_blank"} |
| Unique listener IDs to prevent overwrites                 | Firestore + Storage | Web                 | [#989](https://github.com/capawesome-team/capacitor-firebase/pull/989){:target="_blank"} |
| `DocumentReference` deserializer stack overflow fixed     | Firestore           | Web                 | [#981](https://github.com/capawesome-team/capacitor-firebase/pull/981){:target="_blank"} |
| New `setDefaults(...)` method                             | Remote Config       | Web + iOS + Android | [#970](https://github.com/capawesome-team/capacitor-firebase/pull/970){:target="_blank"} |
| New `getAll()` method                                     | Remote Config       | Web + iOS + Android | [#977](https://github.com/capawesome-team/capacitor-firebase/pull/977){:target="_blank"} |
| `source` exposed on Web                                   | Remote Config       | Web                 | [#979](https://github.com/capawesome-team/capacitor-firebase/pull/979){:target="_blank"} |

## Cloud Firestore

The bulk of this release lands in the [Capacitor Cloud Firestore plugin](../../sdks/capacitor/firebase/cloud-firestore.md).

### More Supported Data Types

Firestore documents can hold more than strings and numbers, but a few of those richer types never made it across the Capacitor bridge intact. The bridge serializes everything to JSON, and JSON has no concept of a document reference, a byte blob, or `NaN`. Version 8.3.0 adds proper round-trip support for all three on Web, iOS, and Android ([#991](https://github.com/capawesome-team/capacitor-firebase/pull/991){:target="_blank"}).

`DocumentReference` and `Bytes` each get a dedicated class, and the non-finite numbers `NaN`, `Infinity`, and `-Infinity` — which JSON would otherwise collapse to `null` — are wrapped so they survive the trip:

```typescript
import {
  Bytes,
  DocumentReference,
  FirebaseFirestore,
} from '@capacitor-firebase/firestore';

await FirebaseFirestore.setDocument({
  reference: 'books/the-pragmatic-programmer',
  data: {
    cover: Bytes.fromUint8Array(coverBytes),
    author: DocumentReference.fromPath('authors/andrew-hunt'),
    rating: Infinity,
  },
});
```

When you read the document back, the values are deserialized for you: the `cover` field becomes a `Bytes` instance again, and `rating` comes back as the real `Infinity` number rather than `null`.

```typescript
const { snapshot } = await FirebaseFirestore.getDocument({
  reference: 'books/the-pragmatic-programmer',
});
const coverBytes = (snapshot.data?.cover as Bytes).toUint8Array();
```

Both classes mirror the Firebase JS SDK. Build a `Bytes` value with `fromBase64String(...)` or `fromUint8Array(...)` and read it with `toBase64()` or `toUint8Array()`, and point a `DocumentReference` at any document with `DocumentReference.fromPath(...)`.

### Queries in `getCountFromServer(...)`

`getCountFromServer(...)` lets you count documents without downloading them — handy for pagination headers or "X results" labels. Until now it could only count an entire collection, so any filtered count meant fetching the documents and counting them client-side.

8.3.0 adds the same `compositeFilter` and `queryConstraints` options that `getCollection(...)` already accepts ([#988](https://github.com/capawesome-team/capacitor-firebase/pull/988){:target="_blank"}), so you can count exactly the subset you care about:

```typescript
const { count } = await FirebaseFirestore.getCountFromServer({
  reference: 'users',
  compositeFilter: {
    type: 'and',
    queryConstraints: [
      {
        type: 'where',
        fieldPath: 'active',
        opStr: '==',
        value: true,
      },
    ],
  },
  queryConstraints: [{ type: 'limit', limit: 100 }],
});
```

Both options are optional, so calling `getCountFromServer(...)` with just a `reference` works exactly as before.

### A `serverTimestamps` Option for Snapshot Listeners

When you write a field with `serverTimestamp()`, the value is filled in by the server. But a snapshot listener fires immediately with your local write, before the server acknowledges it — and in that pending state the timestamp field has no value yet. By default it comes back as `null`.

The new `serverTimestamps` option lets you choose what happens in that window. It's available on `addDocumentSnapshotListener(...)`, `addCollectionSnapshotListener(...)`, and `addCollectionGroupSnapshotListener(...)` ([#993](https://github.com/capawesome-team/capacitor-firebase/pull/993){:target="_blank"}):

```typescript
await FirebaseFirestore.addDocumentSnapshotListener(
  {
    reference: 'users/alice',
    serverTimestamps: 'estimate',
  },
  (event) => {
    console.log(event?.snapshot.data?.lastSeen);
  },
);
```

The three values map directly to the Firebase SDK behavior: `'none'` (the default) returns `null` for pending timestamps, `'estimate'` substitutes the client's best guess at the server time, and `'previous'` returns the field's prior value.

### Bug Fixes

Three fixes round out the Firestore changes:

- **`limitToLast` now works on Android** ([#992](https://github.com/capawesome-team/capacitor-firebase/pull/992){:target="_blank"}). The Android query builder only recognized `limit`, so a `limitToLast` constraint was dropped and threw a `NullPointerException`. It now behaves like iOS.
- **Listeners created in the same millisecond no longer overwrite each other** ([#989](https://github.com/capawesome-team/capacitor-firebase/pull/989){:target="_blank"}). Web listener IDs were timestamp-based; they're now generated uniquely. This fix also applies to the [Capacitor Cloud Storage plugin](../../sdks/capacitor/firebase/cloud-storage.md).
- **`DocumentReference` fields no longer crash the web deserializer** ([#981](https://github.com/capawesome-team/capacitor-firebase/pull/981){:target="_blank"}). A reference field used to trigger a `Maximum call stack size exceeded` error on the web.

## Remote Config

The [Capacitor Remote Config plugin](../../sdks/capacitor/firebase/remote-config.md) gains two new methods and a web improvement.

### `setDefaults(...)`

In-app default values let your app behave sensibly before the first successful fetch — or when the device is offline. 8.3.0 adds `setDefaults(...)` to register them ([#970](https://github.com/capawesome-team/capacitor-firebase/pull/970){:target="_blank"}):

```typescript
await FirebaseRemoteConfig.setDefaults({
  defaults: {
    welcome_message: 'Hello',
    feature_enabled: false,
    max_items: 10,
  },
});
```

Defaults accept strings, numbers, and booleans. Any key you haven't fetched from the server falls back to the value you set here.

### `getAll()`

Reading config values one key at a time gets tedious when you want to inspect everything at once — for a debug screen, say. The new `getAll()` method returns every key/value pair in a single call ([#977](https://github.com/capawesome-team/capacitor-firebase/pull/977){:target="_blank"}):

```typescript
const { values } = await FirebaseRemoteConfig.getAll();

for (const [key, { value, source }] of Object.entries(values)) {
  console.log(`${key} = ${value} (from ${source})`);
}
```

Each entry carries both the value as a string and its `source`, so you can tell whether a value came from the server, a default, or the static fallback.

### `source` Now Available on Web

That `source` field — `Static`, `Default`, or `Remote` — used to be populated only on Android and iOS. It now works on the web too, across `getBoolean(...)`, `getNumber(...)`, `getString(...)`, and `getAll()` ([#979](https://github.com/capawesome-team/capacitor-firebase/pull/979){:target="_blank"}):

```typescript
const { value, source } = await FirebaseRemoteConfig.getString({
  key: 'welcome_message',
});
console.log(value, source); // "Hello" "Remote"
```

Because it's now guaranteed on every platform, `source` is no longer optional in the result types.

## Upgrading

Bump the Capacitor Firebase packages you use to 8.3.0 and sync your native projects:

```bash
npm install @capacitor-firebase/firestore@^8.3.0 @capacitor-firebase/remote-config@^8.3.0
npx cap sync
```

There are no breaking changes in this release. If you're installing either plugin for the first time, the [Cloud Firestore](../../sdks/capacitor/firebase/cloud-firestore.md/#installation) and [Remote Config](../../sdks/capacitor/firebase/remote-config.md/#installation) installation guides walk through the platform setup.

[Subscribe to the Capawesome Newsletter](https://capawesome.io/newsletter/){ .md-button .md-button--primary }

## Related Posts

- [Capacitor Push Notifications: The Complete Guide](./capacitor-push-notifications-guide.md)
- [How to Wrap an Angular App with Capacitor and Firebase](./how-to-wrap-an-angular-app-with-capacitor-and-firebase.md)

## Final Thoughts

If you store references or binary data in Firestore, or you've been counting filtered queries by hand, 8.3.0 is worth the upgrade — those gaps were the kind that forced awkward workarounds. The Remote Config additions are smaller, but a consistent `source` across all three platforms makes config-driven logic easier to reason about.

To go further from here:

- [Capacitor Firestore: Real-Time Data & Offline Sync](./capacitor-firebase-cloud-firestore-guide.md) — use cases, best practices, and the new data types and count queries covered above.
- [Upload & Manage Files with Firebase Storage in Capacitor](./capacitor-firebase-cloud-storage-guide.md) — the plugin sharing the listener ID fix mentioned above.

Got a question or hit an edge case? Drop into the [Capawesome Discord server](https://discord.gg/VCXxSVjefW){:target="_blank"} — we're always happy to help. And to catch the next release write-up in your inbox, subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/){:target="_blank"}.
