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

firestore-sweet

v0.5.2

Published

![alt text](https://warashibe.github.io/firestore-sweet/img/twitter_cover.png "Firestore Sweet")

Readme

alt text

Firestore Sweet

Cloud Firestore made super easy with sweet syntactic sugar

firestore-sweet works with both client-side firebase and server-side firebase-admin.

Project Website / Documentation

https://warashibe.github.io/firestore-sweet/

Installation

yarn add firestore-sweet

Examples

client-side initialization : firebase

import sweet from "firestore-sweet"
import firebase from "firebase"

firebase.initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FIRESTORE PROJECT ID ###'
});

const db = sweet(firebase.firestore)

server-side initialization : firebase-admin

import sweet from "firestore-sweet"
import admin from "firebase-admin"

const serviceAccount = require('path/to/serviceAccountKey.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
})

const db = sweet(admin.firestore)

get

firestore-sweet automatically knows whether the ref is a collection or a doc based on the position. It returns actual data instead of snapshot.

/* for comparisons with the original APIs
   const fs = firebase.firestore() */

// fs.collection("users").get()
await db.get("users")

// fs.collection("users").doc("Bob").get()
await db.get("users", "Bob")

// fs.collection("users").doc("Bob").collection("comments").get()
await db.get("users", "Bob", "comments")

// fs.collection("users").doc("Bob").collection("comments").doc("no3").get()
await db.get("users", "Bob", "comments", "no3")

where orderBy limit

firestore-sweet knows whether the argument is for where, orderBy, or limit based on the array length.

// fs.collection("users").where("age", "==", 20).get()
await db.get("users", ["age", "==", 20])

// fs.collection("users").where("age", "==", 20).orderBy("age", "desc").get()
await db.get("users", ["age", "==", 20], ["age", "desc"])

// fs.collection("users").where("age", "==", 20).orderBy("age", "desc").limit(5).get()
await db.get("users", ["age", "==", 20], ["age", "desc"], 5)

startAt startAfter endAt endBefore

// fs.collection("users").orderBy("age").startAt(20).get()
await db.get("users", ["age"], ["startAt", 20])

add set upsert update delete

// fs.collection("users").doc("Bob").set({name:"Bob", age: 30})
await db.set({name:"Bob", age: 30}, "users", "Bob")

// fs.collection("users").doc("Bob").set({name:"Bob", age: 30}, {merge: true})
await db.upsert({name:"Bob", age: 30}, "users", "Bob")

// fs.collection("users").doc("Bob").update({name:"Bob", age: 30})
await db.update({age: 40}, "users", "Bob")

// fs.collection("users").doc("Bob").delete()
await db.delete("users", "Bob")

delete field : del

// fs.collection("users").doc("Bob").update({age: firebase.firestore.FieldValue.delete()})
await db.update({age: db.del}, "users", "Bob")

increment field : inc(n)

// fs.collection("users").doc("Bob").update({age: firebase.firestore.FieldValue.increment(3)})
await db.update({age: db.inc(3)}, "users", "Bob")

serverTimestamp : ts

// fs.collection("users").doc("Bob").update({date: firebase.firestore.FieldValue.serverTimestamp()})
await db.update({date: db.ts}, "users", "Bob")

arrayUnion : union

// fs.collection("users").doc("Bob").update({favorites: firebase.firestore.FieldValue.arrayUnion("tomato")})
await db.update({favorites: db.union("tomato")}, "users", "Bob")

arrayRemove : remove

// fs.collection("users").doc("Bob").update({favorites: firebase.firestore.FieldValue.arrayRemove("tomato")})
await db.update({favorites: db.remove("tomato")}, "users", "Bob")

onSnapShot : on

const unsubscribe = db.on("users", (docs) => {
  for(const user of docs){
    console.log(`${user.name} : ${user.age}`)
  }
})

drop

This is a unique method only seen in firestore-sweet to delete everything in a collection.

Be careful using it since it's powerful and dangerous if misused.

await db.drop("users")

ref

Use ref to simply get a native ref object from the Firestore SDK.

await db.ref("users", "Bob")

Bulk write operations with query

With firestore sweet, multiple write operations are possible with queries in one method.

This is not something possible with the Firestore APIs. Firestore batch has 500 operations at a time limit, but firestore sweet automatically bypasses the limit by dividing the operations into chunks of 500 and parallelly executes those. It can execute 50,000 operations in a few seconds this way, but watch out for your bill.

add and upsert don't make sense with this operation. add doesn't do anything and upsert works the same as update in this context.

await db.update({age: 30}, "users", ["age", ">", 30])
await db.set({name: "John", age: 30}, "users", ["age", ">", 30])
await db.delete("users", ["age", ">", 30])

runTransaction : tx

await db.tx("users", "Bob", ({ref, t, data}) => {
  t.update(ref, {age: data.age + 10})
})

batch : batch

await db.batch([
  ["set, {name: "Bob", age: 30}, "users", "Bob"],
  ["update", {age: db.inc(3)}, "users", "Bob"],
  ["delete", "users", "Bob"]
])

Getting document ids and snapshots as return values

You can also get document id and snapshot with the actual data by adding K or S to the method names.

get => getK getS / tx => txK txS / on => onK onS

// getK returns document id and data
const users = await db.getK("users")
for(const id in users){
  console.log(`${users[id].name} : ${users[id].age}`)
}

// getS returns Object with snapshot, document id and data
for(const {id, ss , data} of await db.getS("users")){
    const user = ss.data() // same as data
	console.log(`${user.name} : ${user.age}`)
}
  
// getR returns a raw snapshot which is the same behavior as the original firestore API but as an array
(await db.getR("users")).forEach((ss) => {
    const user = ss.data()
	console.log(`${user.name} : ${user.age}`)
}

/* "txK", "txS" and "onK", "onS"
   return the same data as "getK", "getS" respectively */

Test

You need service-account credentials for a Firebase project at /test/.service-account.json to run the tests.

Use a disposable project if you are to run the tests since the tests manipulate and delete actual data from your Firestore.

yarn run test