Skip to content

Observable Collection

ObservableCollection wraps a Firestore collection (or query) with MobX observability. It automatically manages snapshot listeners and exposes a reactive list of documents.

Constructor

ts
new ObservableCollection<T>(
  ref?: CollectionReference<T>,
  queryCreatorFn?: (ref: CollectionReference) => Query,
  options?: Options,
)

The ref parameter is optional because for sub-collections you might not know the full path in advance. Use attachTo() to set the reference later.

The queryCreatorFn receives the collection reference and should return a Firestore Query. It is re-applied automatically when the collection reference changes via attachTo().

Options

OptionTypeDefaultDescription
debugbooleanfalseEnable debug logging to the console.
lazybooleanfalseDefer loading until the collection is observed. See Lazy Loading.
ignoreInitialSnapshotbooleanfalseSkip the first snapshot from the listener.

Properties

PropertyTypeDescription
documentsDocument<T>[]Array of documents, each with id, data, and ref.
isEmptybooleanWhether the collection has no documents.
hasDocumentsbooleanWhether the collection has at least one document.
isLoadingbooleanWhether the collection is currently loading.
pathstring | undefinedThe Firestore path of the collection.
refCollectionReferenceThe collection reference. Throws if not set.

Methods

ready()

Returns a Promise<Document<T>[]> that resolves when documents are first available. If no snapshot listener is active, it performs a one-time fetch.

ts
const docs = await books.ready();

attachTo(ref?: CollectionReference<T>)

Switch to a different collection reference. Pass undefined to detach and clear the documents. Returns this for chaining.

This is commonly used for sub-collections where the path depends on a parent document:

ts
class AuthorStore {
  private _books = createObservableCollection<Book>(undefined);

  loadAuthor(authorId: string) {
    this._books.attachTo(collection(firestore, "authors", authorId, "books"));
  }

  get books() {
    return this._books.documents;
  }
}

If a queryCreatorFn was provided in the constructor, it is automatically re-applied to the new reference.

query (setter)

Change the query of the collection. If the new query is equivalent to the current one (checked via queryEqual), it's a no-op. Pass undefined to clear the query and use the raw collection reference.

ts
books.query = (ref) => query(ref, orderBy("publishedAt", "desc"));

onError

Set an error handler function. Without this, errors are thrown.

ts
books.onError = (err) => console.error(err);

Factory Function

ts
import { createObservableCollection } from "firestore-mobx";

const collection = createObservableCollection(typedCollectionRef);

createObservableCollection infers the type T from the reference, which is useful when working with typed-firestore references where types flow from the ref definitions.

Released under the MIT License.