RxFire
RxFire is an open-source JavaScript library that provides RxJS observable bindings for various Firebase web client SDKs, including Firestore, Realtime Database, Cloud Storage, Authentication, and Functions. Currently at version 6.1.0, it targets Firebase JS SDK v9+ modular APIs and is compatible with RxJS v6 and v7. The library offers observable creators that simplify asynchronous data streams from Firebase, making it portable across frameworks and tree-shakeable. Key differentiators include the ability to easily combine multiple Firebase data sources using RxJS operators and simplify code-splitting of Firebase features, acting as a complementary tool rather than a full wrapper for the Firebase SDK. It is under active maintenance by the Firebase Extended team.
Common errors
-
TypeError: (0 , rxfire_firestore__WEBPACK_IMPORTED_MODULE_2__.collectionData) is not a function
cause This typically occurs when using CommonJS `require()` syntax with an ESM-only library, or when a bundler/Node.js environment is misconfigured for ESM.fixEnsure you are using ESM `import` syntax (`import { collectionData } from 'rxfire/firestore';`) and that your project's build setup (e.g., `package.json` `"type": "module"` or bundler configuration) correctly handles ESM. -
FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created - call initializeApp() first.
cause The Firebase application has not been initialized with `initializeApp()` before attempting to use any Firebase services or RxFire functions that depend on them.fixCall `initializeApp()` from `firebase/app` once at the beginning of your application's lifecycle, providing your Firebase project configuration. -
Error: Can't resolve 'firebase/app' in '...' OR Cannot find package 'firebase/app' imported from ...
cause The `firebase` peer dependency is either missing from your project's `node_modules` or is installed at a version incompatible with RxFire.fixInstall the `firebase` package using `npm install firebase` or `yarn add firebase`. Verify that the installed `firebase` version (`npm view firebase version`) falls within the peer dependency range specified by RxFire (`^9.0.0 || ^10.0.0 || ^11.0.0`). -
Argument of type 'FirebaseApp' is not assignable to parameter of type 'Firestore'.
cause An RxFire function like `collectionData()` (which expects a `Firestore` instance) was incorrectly passed the top-level `FirebaseApp` instance instead of the specific service instance.fixEnsure you pass the correct Firebase service instance. For example, pass `getFirestore(app)` to `collectionData`, `getStorage(app)` to `getDownloadURL`, and `getAuth(app)` to authentication-related RxFire functions.
Warnings
- breaking RxFire v6.0.0 introduced significant breaking changes by migrating its API to align with Firebase JS SDK v9+ modular syntax and updating its RxJS peer dependency to be compatible with RxJS v7. Direct references to `firebase.firestore()` or similar global patterns are no longer supported.
- gotcha RxFire has strict peer dependencies on `firebase` (`^9.0.0 || ^10.0.0 || ^11.0.0`) and `rxjs` (`^6.0.0 || ^7.0.0`). These must be installed separately and at compatible versions, as RxFire does not bundle them.
- gotcha RxFire leverages Firebase JS SDK v9+ modular imports. This means functions are imported from specific subpaths (e.g., `rxfire/firestore`) and core Firebase services must be imported from their respective `firebase/*` subpaths (e.g., `firebase/app`, `firebase/firestore`). Mixing old (e.g., `import firebase from 'firebase'`) and new import styles will lead to errors.
- gotcha The README states 'Status: Beta' despite the package being at version 6.x. While actively maintained, this 'Beta' status might imply that certain APIs could still evolve or that the library might not have reached a final, immutable state typical of a fully stable v1.0+ product in some ecosystems.
- gotcha RxFire functions expect specific Firebase service instances (e.g., `Firestore`, `Storage`, `Auth`) as arguments, not the general `FirebaseApp` instance. Passing the wrong type will result in runtime errors.
Install
-
npm install rxfire -
yarn add rxfire -
pnpm add rxfire
Imports
- collectionData
const { collectionData } = require('rxfire/firestore');import { collectionData } from 'rxfire/firestore'; - getDownloadURL
import getDownloadURL from 'rxfire/storage';
import { getDownloadURL } from 'rxfire/storage'; - initializeApp
import { initializeApp } from 'rxfire/app';import { initializeApp } from 'firebase/app';
Quickstart
import { initializeApp } from 'firebase/app';
import { getFirestore, collection, where, query } from 'firebase/firestore';
import { collectionData } from 'rxfire/firestore';
import { tap } from 'rxjs/operators';
// Replace with your actual Firebase configuration from the Firebase console.
// Using process.env for security in a real application.
const firebaseConfig = {
apiKey: process.env.FIREBASE_API_KEY ?? 'YOUR_API_KEY',
authDomain: process.env.FIREBASE_AUTH_DOMAIN ?? 'your-project-id.firebaseapp.com',
projectId: process.env.FIREBASE_PROJECT_ID ?? 'your-project-id',
storageBucket: process.env.FIREBASE_STORAGE_BUCKET ?? 'your-project-id.appspot.com',
messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID ?? '1234567890',
appId: process.env.FIREBASE_APP_ID ?? '1:1234567890:web:abcdef1234567890'
};
const app = initializeApp(firebaseConfig);
const firestore = getFirestore(app);
// Create a query reference to a 'cities' collection, filtering by 'state' == 'CO'
const citiesRef = query(
collection(firestore, 'cities'),
where('state', '==', 'CO')
);
console.log('Subscribing to real-time city data from Firestore...');
// Use collectionData from RxFire to get an observable of the query snapshot data
collectionData(citiesRef, { idField: 'id' })
.pipe(
tap(cities => console.log(`Received update with ${cities.length} cities.`))
)
.subscribe({
next: cities => {
// This callback will fire initially and then on every subsequent change
console.log('Current cities from Colorado:', cities);
// In a real application, you would update your UI here.
},
error: err => console.error('Error fetching cities:', err),
complete: () => console.log('Observable completed (unlikely for real-time data).')
});
// To demonstrate unsubscribe, in a real app you might do this on component unmount
// const subscription = collectionData(...).subscribe(...);
// setTimeout(() => subscription.unsubscribe(), 30000);