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 🙏

© 2024 – Pkg Stats / Ryan Hefner

firestore-data

v1.0.1

Published

This package gives you a component that makes it easy to bind your Firestore queries to your React components.

Downloads

6

Readme

Firestore Data

npm version npm version

This package gives you a component that makes it easy to bind your Firestore queries to your React components.

There are two ways you can bind your Firestore data to your React component: Function as Child Component and Bind to Local State. The Function as Child Component is easiest to get started while Bind to Local State gives you the most flexibility and can be used in conjunction with server-side rendering (such as Next.js) if that's something you need to do.

Setup

npm i firestore-data

You'll also need an initialized firebase project. I recommend creating a file called firebase.js that looks like the following, with your keys substituted for the public keys below:

import firebase from 'firebase/app'
import 'firebase/firestore'
import 'firebase/auth'
import 'firebase/functions'
import 'firebase/storage'

const firebaseConfig = {
  apiKey: 'AIzaSyBKSk6fpE4XsscB-Id2QGDthUGVZlAVHtc',
  authDomain: 'react-firebase-next.firebaseapp.com',
  databaseURL: 'https://react-firebase-next.firebaseio.com',
  projectId: 'react-firebase-next',
  storageBucket: 'react-firebase-next.appspot.com',
  messagingSenderId: '98853693516',
  appId: '1:98853693516:web:20fc627bb6c0e8f8'
}

// NOTE this prevents firebase from initializing more than once
if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig)
}

const db = firebase.firestore()

export {
  db,
  firebase
}

Then in your application, you can import db from the firebase.js file and use that to run your queries. For example:

Function as Child Component

This is the easiest way to get the data bound and works with functional components. If you're not familiar with the Function as Child Component pattern, check out this article on the subject.

This pattern works with both collection and doc queries. Examples below.

import React from 'react'
import { db } from '../lib/firebase.js'
import Data from 'firestore-data'

export default () => {
  // this component wraps the contents in `Data` which gives it access to `data` and `loading`.
  // `Data` is bound to Firestore and automatically updates whenever the data in the database changes.
  return (
    <Data query={db.collection('locations').doc('my-document-id')}>
      {({ loading, data: location }) => {
        if (loading) return <div>Loading...</div>
        return (
          <div>
            {location.name}
          </div>
        )
      }}
    </Data>
  )
}

When querying a collection, the Data component returns a keyed object rather than an array so you'll need to map over each item to render it. A keyed object is a more common format for Firestore.

import React from 'react'
import { db } from '../lib/firebase.js'
import Data from 'firestore-data'

export default () => {
  return (
    <Data query={db.collection('locations')}>
      {({ loading, data: locations }) => {
        if (loading) return <div>Loading...</div>
        const locationsIndex = Object.keys(locations).map(key => locations[key])
        if (locations.length < 1) {
          return (
            <div>No locations.</div>
          )
        }
        return locationsIndex.map(l => {
          return (
            <div id={l.id}>
              {locations.name}
            </div>
          )
        })
      }}
    </Data>
  )
}

Bind to Local State

You can also bind to local state using the bindTo function. You may want to use this pattern if you want to server-side render your application before binding it to Firestore.

import React from 'react'
import { db } from '../lib/firebase.js'
import Data from 'firestore-data'

export default class App extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      loading: false,
      location: {}
    }
  }
  
  render () {
    if (this.state.loading) return <div>Loading...</div>

    return (
      <>
        <Data query={db.collection('locations').doc('my-document-id')} bindTo={({ loading, data }) => this.setState({ location: data, loading })} />
        <div>
          {this.state.location.name || 'No location'}
        </div>
      </>
    )
  }
}

And this is what you would do if you're using something like Next.js to server-render the page and you want to pre-populate data.

import React from 'react'
import { db } from '../lib/firebase.js'
import Data from 'firestore-data'

export default class App extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      loading: false,
      location: props.location
    }
  }

  // NOTE `getInitialProps` is how Next.js handles server-side rendering
  static getInitialProps = async () => {
    let location = {}
    try {
      const response = await db.collection('locations').doc('my-document-id').get()
      location = response.data()
    } catch (err) {
      console.error(err)
    }
    return { location }
  }
  
  render () {
    if (this.state.loading) return <div>Loading...</div>

    return (
      <>
        <Data query={db.collection('locations').doc('my-document-id')} bindTo={({ loading, data }) => this.setState({ location: data, loading })} />
        <div>
          {this.state.location.name || 'No location'}
        </div>
      </>
    )
  }
}