{"id":13679193,"url":"https://github.com/samuelgozi/firebase-firestore-lite","last_synced_at":"2026-01-11T23:00:48.096Z","repository":{"id":32574373,"uuid":"135850027","full_name":"samuelgozi/firebase-firestore-lite","owner":"samuelgozi","description":"A lightweight cloud firestore library for the browser","archived":false,"fork":false,"pushed_at":"2023-07-18T21:09:50.000Z","size":1096,"stargazers_count":224,"open_issues_count":7,"forks_count":14,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-10-12T15:51:28.479Z","etag":null,"topics":["es6","firebase-database","javascript"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/samuelgozi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-06-02T20:28:04.000Z","updated_at":"2025-08-25T16:05:13.000Z","dependencies_parsed_at":"2024-01-02T23:02:03.801Z","dependency_job_id":"310d991b-71e1-4704-8811-9d3c59a37aff","html_url":"https://github.com/samuelgozi/firebase-firestore-lite","commit_stats":{"total_commits":103,"total_committers":6,"mean_commits":"17.166666666666668","dds":0.2815533980582524,"last_synced_commit":"71178e145f744f5a648010b397995243fbb5446f"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/samuelgozi/firebase-firestore-lite","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samuelgozi%2Ffirebase-firestore-lite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samuelgozi%2Ffirebase-firestore-lite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samuelgozi%2Ffirebase-firestore-lite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samuelgozi%2Ffirebase-firestore-lite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/samuelgozi","download_url":"https://codeload.github.com/samuelgozi/firebase-firestore-lite/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samuelgozi%2Ffirebase-firestore-lite/sbom","scorecard":{"id":798397,"data":{"date":"2025-08-11","repo":{"name":"github.com/samuelgozi/firebase-firestore-lite","commit":"daa44cb662124590e7c5666938b36c095306ec66"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.6,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":1,"reason":"Found 4/29 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:7: update your workflow using https://app.stepsecurity.io/secureworkflow/samuelgozi/firebase-firestore-lite/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:8: update your workflow using https://app.stepsecurity.io/secureworkflow/samuelgozi/firebase-firestore-lite/main.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/samuelgozi/firebase-firestore-lite/main.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/samuelgozi/firebase-firestore-lite/main.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/main.yml:15","Warn: npmCommand not pinned by hash: .github/workflows/main.yml:16","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 6 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"42 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5","Warn: Project is vulnerable to: GHSA-7gc6-qh9x-w6h8","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-vfrc-7r7c-w9mx","Warn: Project is vulnerable to: GHSA-7wwv-vh3v-89cq","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-5v2h-r2cx-5xgj","Warn: Project is vulnerable to: GHSA-rrrm-qjm4-v8hf","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-w7rc-rwvf-8q5r","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T09:41:19.472Z","repository_id":32574373,"created_at":"2025-08-23T09:41:19.472Z","updated_at":"2025-08-23T09:41:19.472Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28326166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T22:11:01.104Z","status":"ssl_error","status_checked_at":"2026-01-11T22:10:58.990Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["es6","firebase-database","javascript"],"created_at":"2024-08-02T13:01:02.962Z","updated_at":"2026-01-11T23:00:48.073Z","avatar_url":"https://github.com/samuelgozi.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","웹"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/samuelgozi/firebase-firestore-lite/master/logo.png\" alt=\"logo\" width=\"400\"/\u003e\n\n[![codecov](https://codecov.io/gh/samuelgozi/firebase-firestore-lite/branch/master/graph/badge.svg)](https://codecov.io/gh/samuelgozi/firebase-firestore-lite) ![bundlephobia](https://badgen.net/bundlephobia/minzip/firebase-auth-lite)\n\n\u003c/p\u003e\n\nThis project goal is to provide an alternative library to the official Firestore JS SDK.\nThe problem with the official library is that it is too heavy ([92kb at the time of writing](https://bundlephobia.com/result?p=@firebase/firestore@1.11.2)),\nand if you include the Auth library as well, and `firebase/app`(which you have to), then it could [add up to hundreds\nof kilobytes without any app logic](https://github.com/samuelgozi/firebase-firestore-lite/wiki/Firebase-Alternative-SDK-Benchmarks#sizes-and-loading-times).\n\n[Our Alternative SDK performs in average 13 times better and is 27 times smaller than the official ones](https://github.com/samuelgozi/firebase-firestore-lite/wiki/Firebase-Alternative-SDK-Benchmarks).\n\n## Calling Firestore from Cloudflare workers\nCurrently all of Google's SDKs, including [javascript version 8](https://firebase.google.com/docs/firestore/quickstart#web-version-8), [javascript version 9](https://firebase.google.com/docs/firestore/quickstart#web-version-9), [firebase-admin](https://firebase.google.com/docs/firestore/quickstart#node.js) and [google-cloud/firestore](https://cloud.google.com/nodejs/docs/reference/firestore/latest#installing-the-client-library), do not work in Cloudflare's workers environment due to dependency on certain Node libraries that do not exist in this environemnt. \nThis package can be used in Cloudflare Workers to access Firestore database.\n\nSee below how to authenticate from workers environment.\n\n## What am I giving up by using this?\n\nNo realtime support (yet*) and no out of the box offline support*. You should also transpile and polyfill the code yourself for your target browsers. I don't try to support old browsers (ehm... IE), but it is possible and was done by some of the community.\n\n\\* Realtime is planned, but will take some time because of lack of documentation on how the API works.\n\n\\* Offline support will be available in the future, but probably as a third-party addition, and is currently not a high priority.\n\n## API Reference\n\nYou can access the full API Reference here: https://samuelgozi.github.io/firebase-firestore-lite/\n\n## Getting started\n\n### NPM\n\nInstall this package with NPM/Yarn:\n\n```bash\nnpm install firebase-firestore-lite\n\n# or\n\nyarn add firebase-firestore-lite\n```\n\n## Create a Database instance\n\nIt is possible to use authentication but not necessary.\nFirst I'll show you how to use it without it:\n\n```js\nimport { Database } from 'firebase-firestore-lite';\n\n// All you need is the projectId. It can be found on the firebase console and in the firebase config.\nconst db = new Database({ projectId: 'sandbox' });\n```\n\nNow you can start working with the database.\n\nMost apps apply some kind of user-based restrictions. If you want to access the database as an authenticated user it can be done with the [\"firebase-auth-lite\"](https://github.com/samuelgozi/firebase-auth-lite) library. Here's how:\n\n```js\nimport { Database } from 'firebase-firestore-lite';\nimport Auth from 'firebase-auth-lite';\n\n// Please read the docs on Auth library for further instructions on all the Auth features.\nconst auth = new Auth({\n\tapiKey: '[The Firebase API key]'\n});\n\n// Now pass the auth instance as well as the projectId.\nconst db = new Database({ projectId: 'sandbox', auth });\n```\n\nThe firestore instance will now make all the requests with the authenticates user's credentials.\n\n### Authenticating from Cloudflare's workers\nYou can create your own authorization provider that will use a service-user credentials to authenticate. \nTo do that, pass an `auth` object to the DB constructor:\nThe code below assumes that you have a KV store mapped to `PROPERTIES` in your `wrangler.toml` file,\nthat contains a key called `GOOGLE_FIRESTORE_ACCESS_TOKEN` with an access token.\nCheckout [this gist](https://gist.github.com/danbars/d39bad619db29669cebccf464d9e66e5) for an example how to create such a token.\n\n```javascript\n/* global PROPERTIES */\nconst auth = {\n  /**\n  * Uses native fetch, but adds authorization headers, otherwise, the API is exactly the same as native fetch.\n  * @param {Request|Object|string} resource A request to send. It can be a resource or an options object.\n  * @param {Object} init An options object.\n  */\n  authorizedRequest: async (resource, init) =\u003e {\n    const request = resource instanceof Request ? resource : new Request(resource, init);\n    const token = await PROPERTIES.get('GOOGLE_FIRESTORE_ACCESS_TOKEN', {cacheTtl: 600})\n    request.headers.set('Authorization', `Bearer ${token}`);\n    return fetch(request);\n  }\n}\nconst db = new Database({ projectId: 'sandbox', auth });\n```\n\n## Working with references\n\nReferences point to specific documents or collections in a database. A reference doesn't really know anything about the data itself, in fact, you can and will use references with documents that don't even exist.\n\nA Reference is just a helper class that encapsulates some helpful methods that are designed to save us (the devs) some time. But in their essence, they are just a fancy abstraction over paths.\n\nLet's create one:\n\n```js\n// Reference to a collection\nconst usersCollection = db.ref('users');\n\n// Reference to a document\nconst samuel = db.ref('users/samuel');\n```\n\n`usersCollection` points to a collection. The way we know it is because of the path. The path is `users` and we know that the root of the database only has collections. So, it is the same as writing `/users`.\n\n`samuel` points to a document because the path we used to create it was a path to a document.\n\nWe can also create a reference to the root of the database:\n\n```js\nconst root = db.ref('/');\n\n// Or\n\nconst root = db.ref('');\n```\n\n### Reference's props and methods\n\nA reference has some helpful instance methods and properties.\nPlease read more about them in the [API Reference](https://github.com/samuelgozi/firebase-auth-lite).\n\n## Add and manage data\n\nThere are multiple ways to manipulate data in Firestore:\n\n- Directly getting, adding, updating or deleting by using a `Reference`.\n- Getting all documents within a collection.\n- `batchGet` to retrieve a list of documents.\n- `Transaction` to either batch write or read and write at the same time.\n\n### Get a document\n\nYou can use `get` to fetch a single document from the database.\n\n```js\nconst ref = db.ref('users/samuel');\nconst doc = await ref.get(); // Returns an instance of Document\n```\n\n### Get all the documents in a collection\n\nYou can use `list` to fetch a all the documents in a collection.\nBe mindful that this request is expensive in terms of bandwidth and writes.\n\n```js\nconst ref = db.ref('users');\nconst doc = await ref.list(); // Returns an instance of List\n```\n\n### Add a document\n\nThis method is only accessible through collection references. It will create a document with a randomly generated name.\n\n```js\n// Create a reference to the collection to which the new document will be added\nconst ref = db.ref('users');\n\n// Creates the new document with the provided data, and if successful it will return a Reference it.\nconst newRef = await ref.add({\n\temail: 'samuel@example.com'\n});\n\nconsole.log(newRef.id); // q9YUI8CQWa1KEYgZTK6t\n```\n\n### Set a document\n\nSet can be used to create/update a document with a known ID.\n\nIf the document does not exist, it will be created. If the document does exist, its contents will be overwritten with the newly provided data. If you want to merge the data instead, use the \"update\" (below) method.\n\n```js\nconst ref = db.ref('users/samuel');\n\nawait ref.set({\n\temail: 'samuel@example.com'\n});\n```\n\n### Update a document\n\nThe `update` method will merge the data passed to it with the data of the document in the database and the write will fail if the document doesn't exist.\n\n```js\nawait ref.update({\n\tprofession: 'web-dev'\n});\n```\n\n### Delete a document\n\nThis will delete the document from the database.\n\n```js\nref.delete(); // Returns a promise that resolves if deleted successfully.\n```\n\nJust like that, it's gone.\n\n## Batch reads\n\nIt is possible to get multiple documents with one request by using the `db.batchGet` method.\n\nThe `batchGet` method can receives an array of References (of documents) or if you prefer you can just pass the paths.\n\n```js\n// Using an array of references:\nconst doc1 = db.ref('col/doc1');\nconst doc2 = db.ref('col/doc2');\nconst doc3 = db.ref('col/doc3');\n\nconst docs = await db.batchGet([doc1, doc2, doc3]);\nconst sameDocs = await db.batchGet(['col/doc1', 'col/doc2', 'col/doc3']);\n```\n\nAs you can see, using document paths instead of references is much cleaner, and it also performs a tiny bit better.\n\nThis method will return an array of `Document` instances.\n\n## Transactions and batch writes\n\nTransactions allow us to perform batch reads, or reads and writes. All of the operations done as a part of a transaction are atomic; Either all of them succeed, or none of them are applied.\n\nThey are subject to the [Quotas and Limits of Firestore](https://firebase.google.com/docs/firestore/quotas#writes_and_transactions), so make sure you read them.\n\nLet's start with a batch write. First, we create a transaction:\n\n```js\nconst tx = db.transaction();\n```\n\nNow `tx` holds a `Transaction` instance. The instance has four methods that help us describe operations:\n\n- `add` Add a document with a randomly generated id to a collection.\n- `set` Add or overwrite a document.\n- `update` Update (merge) data of an existing document.\n- `delete` Delete a document.\n\nThese methods do not make any network requests yet. They are just helpers to describe the operations to be done as part of this transaction. In order to commit those changes, we use the `commit` method. Now let's describe the transaction, and then commit it:\n\n```js\n// Add a new document with a random id\ntx.add('users', { name: 'random', email: 'random@example.com' });\n// Create a new document or overwrite an existing one.\ntx.set('users/samuel', { name: 'samuel', email: 'samuel@example.com' });\n// Update an existing document.\ntx.update('users/daniel', { email: 'newEmail@example.com' });\n// Delete a document.\ntx.delete('users/george');\n\n// Now let's commit them. This one is asynchronous and does\n// indeed make the request.\ntry {\n\tawait tx.commit();\n} catch (e) {\n\t// Handle the failed transaction.\n}\n```\n\n### Read and write in a transaction\n\nA transaction is very powerful because you can use it to perform operations that depend on the current data of a document. Sometimes it is necessary to have a guarantee that we are working with the latest data. Using reads within a transaction can help us accomplish that.\n\nIntroducing the `get` method. It works exactly as a `batchGet`, and that makes it different than the other `Transaction` methods because it is asynchronous.\n\nWhen using the `get` method inside a transaction we make sure that any write operation on a document returned from it will be atomic. So, if the data in that document changed concurrently, and the one we have is no longer up-to-date, the whole transaction will fail.\n\nHere is how you can use it:\n\n```js\nconst tx = db.transaction();\nconst [doc1, doc2, doc3] = await tx.get(['col/doc1', 'col/doc2', 'col/doc3']);\n\n// Work and change the data.\n\ntx.set('col/doc1', doc1);\ntx.update('col/doc2', doc2);\ntx.delete('col/doc3', doc3);\n\n// Lastly, commit.\nawait commit();\n```\n\nIf you end up using the same Document instances returned from the\n`tx.get` method, then there is no need to pass the document path\nagain and again when describing an operations. You can omit the path\nand just pass the Document instance instead:\n\n```js\n// Instead of\ntx.set('col/doc1', doc1);\ntx.update('col/doc2', doc2);\ntx.delete('col/doc3', doc3);\n\n// Do\ntx.set(doc1);\ntx.update(doc2);\ntx.delete(doc3);\n```\n\nBut remember, this works only if you pass the same document instance returned from the `tx.get()` method. If you end up generating a new object, then you have to pass the path to it.\n\n### The `runTransaction` method\n\nThere is a cleaner way to make a transaction with writes, and can also help you retry the transaction when failed.\n\nThe `db.runTransaction()` method can help you keep things cleaner.\nIt receives a function as its first argument, and the number of attempts as the second argument (defaults to 5).\n\nIt will commit and retry the function for you if the transaction fails because the data changed, but it will throw immediately if the code failed due to any other reason.\n\nHere is how you can use it:\n\n```js\nasync function updateFunction(tx) {\n\tconst [doc1, doc2, doc3] = await tx.get([ ... ]);\n\n\t// Manipulate the data.\n\tdoc1.title = 'new title';\n\t// ...\n\n\ttx.update('col/doc1', doc1);\n}\n\n// Will resolve if and when the transaction is done.\n// Will try up to 10 times.\nawait db.runTransaction(updateFunction, 10);\n```\n\n## Queries\n\nQueries are done by using the `query` method of a reference instance. The query will search through the children of document/collection.\n\nlet's look at an example:\n\n```js\nconst users = db.ref('users');\nconst usersQuery = users.query({\n\twhere: [['age', '=\u003e', 21]], // Array of query operations.\n\torderBy: 'age', // Can also be an object { field: 'age', direction: 'asc'|'desc' }\n\tlimit: 10 // The max results\n});\n\n// The above will be identical to\nconst usersQuery = users\n\t.query()\n\t.where('age', '=\u003e', 21)\n\t.orderBy('age')\n\t.limit(10);\n```\n\nThe `users.query()` method optionally accepts an options object, and then returns a new Query instance. All the options can also be set by using the query methods, and they can also be chained (as seen in the second example). You can then `run()` the query:\n\n```js\nconst results = await usersQuery.run(); // Will return the query results.\n```\n\nAll the query options can be seen in the [API reference for Query](https://github.com/samuelgozi/firebase-firestore-lite/wiki/Query-instance#queryoptions--object), bet here is a quick recap of the important ones:\n\n- `select` Array of field paths to be returned, when empty will return the whole document.\n- `where` Comparative operations for filtering the query.\n- `from` Set by default for your current collection of the reference.\n- `orderBy` The field and direction to order by.\n- `startAt` A Document instance to start the query from.\n- `endAt` A Document instance at which to end the query.\n- `offset` Number of results to skip\n- `limit` The maximum number of documents to return.\n\n## Collection Group Queries\n\nSometimes you want to query all collections with a certain name.\nLets say for example that you have a collection called `users` which contains the users of your app.\nEach user document inside of that collection has a child collection called `posts`, at it contains all of the posts that user has published.\n\nWhat if I want to make a query that will search all the posts regardless of which user created it?\nWell, in order to do that you will want to query a \"Collection Group\", and this is done from the `Database` instance:\n\n```js\nconst query = db.collectionGroup('posts');\n```\n\nThis will return a query that will be performed on all collections called `posts`.\n\nBut what if we want to narrow the scope of the query? For example, lets say that we have a `sections` collection,\nwith the _documents_ `movies` and `songs`, which represent different type of content. Each one of them has a `posts` collection with `post` documents, and each of these has a `comments` collection with the comments on each `post`.\n\nIf we only want to query the `comments` collection that are children of the `songs` _document_ we can do that by using one of the options of the `collectionGroup` method:\n\n```js\nconst songsDoc = db.ref('sections/songs');\nconst query = db.collectionGroup('comments', { parent: songsDoc });\n```\n\nThe returned query will not include documents of the `comments` collection that are children of the `movies` document.\n_NOTE:_ The parent has to be a document, you will need to organize your data accordingly.\n\n## Firestore emulator\n\nIn order to configure the library to work with the Firestore emulator we need to change two settings when creating the Database instance.\n\n- `host` set it to `localhost:8080` to work with the official emulator.\n- `ssl` set to false.\n\nThis is how it would look:\n\n```js\nconst db = new Database({\n\tprojectId: 'sandbox',\n\thost: 'localhost:8080',\n\tssl: false\n});\n```\n\n## Contributing\n\nI very much welcome any contribution. Grammar issues, docs, examples, features requests, and code. But please open an issue before so that you don't work on anything that someone else is.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamuelgozi%2Ffirebase-firestore-lite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamuelgozi%2Ffirebase-firestore-lite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamuelgozi%2Ffirebase-firestore-lite/lists"}