0.8.2 • Published 2 years ago

@tim-code/firestore-util v0.8.2

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

firestore-util

npm install @tim-code/firestore-util

Philosophy

The Firestore SDK exposes a lot of functionality; however, it could be easier to use especially for common operations.

batch operations are key to controlling the number of network requests; however, there can only be 500 operations in one batch.

This zero-dependency library offers common operations such as insert, update, move, copy, and remove that make use of batch correctly.

To support this, query is also offered with where and limit options to allow for a query to be specified with a write operation.

Example

import { Firestore } from "@google-cloud/firestore"
import { query, unbox } from "./src/query.js"

const db = new Firestore() // assumes your environment variables are setup correctly
const collection = "..."
query(db, collection).then(unbox).then(console.log)

Six Functions

query(db, collection, { where, orderBy, limit })

Returns documents that match a query using Firestore's get function.

where is an object and supports some typical NoSQL syntax: $lt, $gt, $lte, $gte, $ne, $eq. Examples: where: {date: "2021-01-01"}} or where: {date: {$gte: "2021-01-01", $lte: 2022-01-01}}

where can also contain arrays which correspond to Firestore in clauses: where: {date: ["2021-01-01", "2021-01-02"]}

orderBy can be a field name, an array of field names, or an object which specifies order: orderBy: {name: "desc"}.

limit restricts the amount of documents returned. By default, it is 500.

unbox() is an another exported function that will return the actual documents when passed the query result as in the introductory example.

insert(db, collection, [[id1, data1], [id2, data2], ...], {merge})

Insert documents using Firestore's set function.

When merge is truthy, insert() will deep merge the data being inserted with an existing document if they would have the same ID. If not truthy and there would be two documents with same ID resulting from an insert, an error will be thrown.

https://stackoverflow.com/questions/46597327/difference-between-set-with-merge-true-and-update

update(db, collection, { transform, where, limit })

Update documents using a callback and Firestore's update function.

transform is a callback that is passed a document and is expected to return a document update. This does not need to be an entire document.

where uses the same syntax as query().

limit is optional. It does not affect the number of documents changed. Rather, it limits how many documents are updated at once. See below for details on why this might be useful.

In the following functions, where and limit do the same sort of things.

copy(db, collection, { name, where, transform, limit })

Copy documents from one collection to another using set.

name is an optional callback that is passed a document and its old ID. By default, it is (element, oldId) => oldId

transform is optional.

name and transform do the same sort of things for move().

move(db, collection, { name, where, transform, limit })

Move documents from one collection to another using delete and set.

remove(db, collection, { where, limit })

Remove documents using Firestore's delete function

Performance with Parallel Write Operations

Firestore only allows 10000 writes in one second. By default, firestore-util limits the write operations possible in one second to 2000 due to one call of a firestore-util function. This can be increased or decreased by changing the limit parameter to the function:

import { insert } from "firestore-util"
// allow theoretical maximum writes per second
insert(db, "collection", data, { limit: 10000 })

"Transaction too big. Decrease transaction size."

Firestore limits how large a transaction and batch can be.

Limit how many documents are modified across all batches in a one second iteration by setting the limit parameter:

import { remove } from "firestore-util"
remove(db, collection, { where: [], limit: 100 })

"Deadline Exceeded"

From https://github.com/firebase/firebase-admin-node/issues/499:

"Generally, a deadline exceeded error indicates that the rpc took too long to complete. Firestore sets a deadline of 60s, so I'd expect these errors to occur pretty much precisely 60s after the query was initiated. I suppose an exceptionally large query could cause this to occur, or perhaps your process being preempted for 60s(!)."

Basically, this error occurs when data isn't being processed quickly enough by Firestore servers.

Firestore has a commonly overlooked limit: "Maximum write rate to a collection in which documents contain sequential values in an indexed field" of 500 per second.

A common example of this sort of field are timestamps. The best solution is to add an exemption to such fields.

https://stackoverflow.com/questions/55818648/firestore-500-writes-per-second-to-one-collection

Environment Variables

To aid testing, there are a few environment variables which create large tests and are used in package.json. These do not need to be set.

TEST_SIZE: the number of objects to put into the database

BATCH_SIZE: the number of objects to put into a batch

CONCURRENT: the number of batches executed in parallel

0.8.1

2 years ago

0.8.2

2 years ago

0.6.3

2 years ago

0.8.0

2 years ago

0.6.2

2 years ago

0.7.0

2 years ago

0.3.13

2 years ago

0.5.0

2 years ago

0.4.1

2 years ago

0.4.0

2 years ago

0.6.1

2 years ago

0.5.2

2 years ago

0.6.0

2 years ago

0.5.1

2 years ago

0.3.12

2 years ago

0.3.11

2 years ago

0.3.9

2 years ago

0.3.8

2 years ago

0.3.7

2 years ago

0.3.6

2 years ago

0.3.5

2 years ago

0.3.4

2 years ago

0.3.3

2 years ago

0.3.2

2 years ago

0.3.1

2 years ago

0.3.0

2 years ago

0.2.7

2 years ago

0.2.6

2 years ago

0.2.5

2 years ago

0.2.4

2 years ago

0.2.2

2 years ago

0.2.0

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago

0.0.2

3 years ago

0.0.1

3 years ago