@movinjuma/firestore
v0.0.2
Published
firestore in non node environments like browsers and other plain javascript environment
Maintainers
Readme
cloudflare-firestore
Lightweight, tree-shakeable Firestore REST client focused on Cloudflare Workers and other non-Node environments.
Overview
- Lightweight wrappers around the Google Firestore REST API.
- Two client constructors:
CloudFirestore(regional, usesfirestore.{region}.rep.googleapis.com) andFirebaseFirestore(globalfirestore.googleapis.com). - Modular exports so consumers can import only the functions they need for tree-shaking.
- Strong TypeScript support: typed client,
WhereClausefilters, and generic document payload helpers.
Key exports
CloudFirestore(opts): create a client for Google Cloud Firestore (regional endpoint).FirebaseFirestore(opts): create a client for Firebase/Cloud Firestore (global endpoint).getCollection({ client, collection }): create a collection reference used by other helpers. Returns{ client, collection }.getDoc({ collection, documentId, fields? }): read a single document. Returns{ id, data }withdatadecoded to plain JS values.createDoc({ collection, data }): create a document with a server-generated id. Returns{ id, data }.setDoc({ collection, documentId, data }): create/replace a document atdocumentId. Returns{ id, data }.updateDoc({ collection, documentId, partialData }): partial update usingupdateMaskto only change provided fields. Returns{ id, data }.deleteDoc({ collection, documentId }): deletes a document. Returns{ success: true }.filterDoc({ collection, where | WhereClause[] }): runs a structured query viarunQuery. Returns an array of{ id, data }.createBulk({ collection, items }),setBulk({ collection, items }),updateBulk({ collection, items }): bulk operations that accept acollectionref and arrays of items; they attempt rollback on partial failures and throwAggregateErroron failure.deleteBulk({ collection, ids }): delete multiple documents by id. On partial failure the library attempts to restore successfully deleted documents from snapshots and throws anAggregateErrordescribing failures.deleteByField({ collection, field, value }): delete documents wherefield == value; usesfilterDocto find matches then delegates todeleteBulk.
Types
FirestoreClient:{ projectId, databaseId, baseUrl, documentsUrl, Authorization }— returned byCloudFirestore/FirebaseFirestore.DocumentData:Record<string, any>— the decoded JS document data.WhereClause:{ field: string; op: Operator; value: any }whereOperatoris strongly typed to Firestore operators such as==,>,array-contains, etc.
Usage examples
Create a client (Cloud Firestore regional):
import { CloudFirestore, getCollection, getDoc, createDoc, filterDoc } from '@cloudflare/firestore';
const client = CloudFirestore({ token: 'BEARER_TOKEN', region: 'us-central1', projectId: 'my-project' });
const col = getCollection({ client, collection: 'users' });
// Create a document with server-generated ID
// For typed results define an interface matching the document shape
interface User { name: string; age: number; }
const created = await createDoc<User>({ collection: col, data: { name: 'Alice', age: 30 } });
// created -> { id: 'generatedId', data: { name: 'Alice', age: 30 } } // data is typed as `User`
// Read a document with typed response
const doc = await getDoc<User>({ collection: col, documentId: created.id! });
// doc.data is `User | null` so check for null before accessing fields
// Query with filters (typed)
import type { WhereClause } from './src/types';
const where: WhereClause = { field: 'name', op: '==', value: 'Alice' };
const results = await filterDoc<User>({ collection: col, where });
// Bulk update example
```ts
import { updateBulk } from '@cloudflare/firestore';
interface User { name: string; age: number }
try {
await updateBulk<User>({ client, collectionPath: 'users', items: [
{ docId: 'a', data: { age: 31 } },
{ docId: 'b', data: { name: 'Updated' } },
]});
} catch (err: any) {
// err is an AggregateError containing individual operation errors
console.error('Bulk update failed', err);
}
// Bulk delete example — delete by ids
```ts
import { deleteBulk } from '@cloudflare/firestore';
await deleteBulk({ client, collectionPath: 'users', ids: ['id1', 'id2', 'id3'] });// Delete by field equality
import { deleteByField } from '@cloudflare/firestore';
// Removes all documents where `status === 'inactive'` (equality match)
await deleteByField({ client, collectionPath: 'users', field: 'status', value: 'inactive' });Notes and behavior
- Projections:
getDoc({ ..., fields? })accepts an array of field names to return (usesmask.fieldPathsunder the REST API). - Projections & typing: Use generics to declare the expected document shape (e.g.
User). Returneddatais typed as that interface ornullwhen the document has no fields. Example:getDoc<User>({ client, collectionPath: 'users', documentId: 'id', fields: ['name'] })yieldsdata: Pick<User, 'name'> | nullat compile time when you provide the field list. updateDocusesupdateMask.fieldPathsto only update specified fields inpartialData.- All methods expect an OAuth
Bearertoken passed astokenwhen constructing the client; theAuthorizationheader is set for you. Collection({ client, collection })returns{ client, collection }. Helper functions accept a single options object with named parameters (e.g.{ client, collectionPath, documentId }). This keeps the surface minimal and tree-shakeable while providing clearer call sites.
Compatibility
- Works in Cloudflare Workers, browsers, and other environments that provide
fetchand standard Web APIs.
Example: Cloudflare Worker
Below is a minimal module-worker example (see examples/worker.ts) showing how to read a secret token and call getDoc with typed results.
- Add a Worker secret for the Firestore token:
wrangler secret put FIRESTORE_TOKEN- Example worker (module format) —
examples/worker.ts:
import { CloudFirestore, getDoc } from '@cloudflare/firestore';
interface User { name: string; age: number }
export default {
async fetch(request, env) {
const token = env.FIRESTORE_TOKEN;
const client = CloudFirestore({ token, region: 'us-central1', projectId: 'my-project' });
try {
const doc = await getDoc<User>({ client, collectionPath: 'users', documentId: 'alice' });
return new Response(JSON.stringify(doc), { headers: { 'Content-Type': 'application/json' } });
} catch (err) {
return new Response(String(err?.message ?? err), { status: 502 });
}
}
}Notes:
- Import the package normally when installed from npm; in local example we reference
dist/index.js. - Use Wrangler to publish the module worker.
Contributing & publishing
- Build with
tscto generatedist/and type declarations.
npm run buildLicense: MIT
