npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nextbone-firestore

v0.9.2

Published

Classes to use Firestore with Nextbone

Downloads

126

Readme

nextbone-firestore

NPM version NPM downloads

nextbone-firestore is a Nextbone binding for Firestore

Features

  • ✅ Fetch data on demand or listen for changes in real time
  • ✅ Bind for documents or collections
  • ✅ Tracking of reference / query params changes
  • ✅ Custom Firestore converters support
  • ✅ TypeScript type definitions included

Installation

npm install nextbone-firestore nextbone firebase
# or
yarn add nextbone-firestore nextbone firebase

Requirements

  • Firebase Web SDK v9+ (modular API)
  • Nextbone

Quick Start

Setup Firebase

First, ensure Firebase is properly installed and configured:

import { initializeApp } from 'firebase/app'

const app = initializeApp({
  // your firebase config
})

Basic Model (FireModel)

Use FireModel for simple CRUD operations without real-time updates:

import { FireModel } from 'nextbone-firestore'
import { collection, doc, getFirestore } from 'firebase/firestore'

const db = getFirestore()

class User extends FireModel {
  collectionRef() {
    return collection(db, 'users')
  }
}

// Create a new user
const user = new User({ name: 'John', email: '[email protected]' })
await user.save()
console.log(user.id) // auto-generated Firestore ID

// Fetch an existing user
const existingUser = new User({ id: 'user-123' })
await existingUser.fetch()
console.log(existingUser.get('name'))

// Update a user
existingUser.set('name', 'Jane')
await existingUser.save()

// Delete a user
await existingUser.destroy()

Observable Model (ObservableModel)

Use ObservableModel for real-time synchronization with reactive params.

Example setting doc path through params:

import { ObservableModel } from 'nextbone-firestore'
import { query, where } from 'firebase/firestore'

class LiveUser extends ObservableModel {
  path(params) {
    if (params.orgId && params.userId) {
      return `organizations/${params.orgId}/users/${params.userId}`
    }
  }
}

const user = new LiveUser()

// params are used in path()
user.params.orgId = 'org-123'
user.params.userId = 'user-456'

// Start real-time sync
user.observe()

// Wait for initial data
await user.ready()

console.log(user.attributes) // { id: 'user-456', name: '...', ... }

// Stop observing when done
user.unobserve()

Example without path defined:

When path() is not defined or returns falsy, the model listens to a collection using the path returned by collectionPath and the constraints defined in query. By default, the first document is selected, being possible to customize using selectSnapshot.

import { ObservableModel } from 'nextbone-firestore'
import { query, where, orderBy, limit } from 'firebase/firestore'

class BaseSynchronization extends ObservableModel {
  collectionPath(params) {
    return `organizations/${params.orgId}/synchronizations`
  }

  query(ref) {
    return query(
      ref,
      where('status', '==', 'completed'),
      orderBy('timestamp', 'desc'),
      limit(2)
    )
  }
}

class LastSynchronization extends BaseSynchronization {}

class PreviousSynchronization extends BaseSynchronization {
  selectSnapshot(snapshot) {
    // Select the second document from the query results
    return snapshot.docs[1]
  }
}

const last = new LastSynchronization()
// orgId is used in collectionPath
last.params.orgId = 'org-123'

// Start real-time sync
last.observe()

// Wait for initial data
await last.ready()

console.log(last.attributes) // { id: '...', status: 'completed', timestamp: ..., ... }

const previous = new PreviousSynchronization()

previous.params.orgId = 'org-123'

previous.observe()

await previous.ready()

console.log(previous.attributes) // { id: '...', status: 'completed', timestamp: ..., ... }

Collection (FireCollection)

Use FireCollection for managing multiple documents:

import { FireCollection } from 'nextbone-firestore'
import { query, where, orderBy } from 'firebase/firestore'

class Patients extends FireCollection {
  path(params) {
    return `clinics/${params.clinicId}/patients`
  }

  query(ref, params) {
    let q = ref
    if (!params.includeInactive) {
      q = query(q, where('active', '==', true))
    }
    return query(q, orderBy('name'))
  }
}

const patients = new Patients()
patients.params.clinicId = 'clinic-1'

// One-time fetch
await patients.fetch()

// Or observe in real-time
patients.observe()
await patients.ready()

// React to data
patients.forEach((patient) => {
  console.log(patient.get('name'))
})

// Update params triggers automatic re-fetch when observing
patients.params.includeInactive = true
await patients.ready()

// Stop observing
patients.unobserve()

Custom Converters

Use Firestore converters to transform data between your app and Firestore:

import { FireCollection, ObservableModel } from 'nextbone-firestore'
import { Timestamp } from 'firebase/firestore'

// Define a converter
const userConverter = {
  toFirestore(data) {
    return {
      ...data,
      createdAt: Timestamp.fromDate(data.createdAt),
      updatedAt: Timestamp.now(),
    }
  },
  fromFirestore(snapshot, options) {
    const data = snapshot.data(options)
    return {
      ...data,
      createdAt: data.createdAt?.toDate(),
      updatedAt: data.updatedAt?.toDate(),
    }
  },
}

// Apply to a Collection
class Users extends FireCollection {
  static converter = userConverter

  path() {
    return 'users'
  }
}

// Apply to an ObservableModel
class LiveUser extends ObservableModel {
  static converter = userConverter

  collectionPath() {
    return 'users'
  }

  query(ref) {
    return query(ref, where('active', '==', true))
  }
}

Documentation

For comprehensive documentation, see:

Class Overview

| Class | Use Case | | ----------------- | ----------------------------------------------------------- | | FireModel | Simple CRUD operations for single documents | | ObservableModel | Real-time sync with reactive params for single documents | | FireCollection | Managing multiple documents with queries and real-time sync |

Get in Touch

License

Copyright © 2021 - 2025 Luiz Américo. This source code is licensed under the MIT license found in the LICENSE.txt file. The documentation to the project is licensed under the CC BY-SA 4.0 license.


Made by Luiz Américo