https://github.com/olegkorol/firestore-admin
A simple Firestore client for Deno.
https://github.com/olegkorol/firestore-admin
deno firebase firestore firestore-admin google-cloud jsr
Last synced: 12 months ago
JSON representation
A simple Firestore client for Deno.
- Host: GitHub
- URL: https://github.com/olegkorol/firestore-admin
- Owner: olegkorol
- License: gpl-3.0
- Created: 2024-10-24T04:30:12.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-10-24T12:27:50.000Z (over 1 year ago)
- Last Synced: 2024-10-24T22:25:14.775Z (over 1 year ago)
- Topics: deno, firebase, firestore, firestore-admin, google-cloud, jsr
- Language: TypeScript
- Homepage: https://jsr.io/@koiztech/firestore-admin
- Size: 34.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Firestore Admin Client for Deno
This is a simple Firestore Admin Client implemented for Deno. It provides an
easy-to-use interface for interacting with Firestore databases using the Google
Cloud Firestore API.
## Features
- Authentication using Google Service Account
- Automatic token refresh
- CRUD operations on Firestore documents
- Support for querying collections
- Conversion between Firestore document format and JSON
## Prerequisites
- Deno installed on your system
- A Google Cloud project with Firestore enabled
- A service account JSON file with the necessary permissions
## Setup
1. Set the `FIREBASE_SERVICE_ACCOUNT` environment variable with the contents of
your service account JSON file.
You can set this environment variable in a `.env` file (do not forget to add the
`--env` flag when running your script):
```text
# .env
FIREBASE_SERVICE_ACCOUNT='{
"type": "service_account",
"project_id": "XXX",
"private_key_id": "XXX",
"private_key": "XXX",
"client_email": "XXX@XXX.iam.gserviceaccount.com",
"client_id": "XXX",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/XXX.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}'
```
2. Install `@koiztech/firestore-admin` as a dependency:
```bash
deno add jsr:@koiztech/firestore-admin
```
3. Import `FirestoreAdminClient` in your Deno script and initialise it:
```typescript
import { FirestoreAdminClient } from "@koiztech/firestore-admin";
const firestore = new FirestoreAdminClient();
```
## Usage
`firestore-admin` will take care of parsing the data to/from JSON when
fetching/updating documents.
If you work with Firestore Timestamp fields, read the
[Using timestamps](#using-timestamps) section.
If you need to query
documents by their ID, read the [Using document IDs in a filter](#using-document-ids-in-a-filter)
section.
### Create a document
```typescript
const document = await firestore.createDocument("my-collection", {
name: "John Doe",
});
// document = {
// _id: 'XXX',
// _path: 'my-collection/XXX',
// name: 'John Doe',
// }
```
Returns the created document with an additional `_id` and `_path` fields, which
are the document ID and path respectively.
### List all documents in a collection
```typescript
const documents = await firestore.listDocumentsInCollection("my-collection");
// documents = ['document1', 'document2']
```
Returns an array of document IDs.
### Fetch all documents in a collection
Note: The fetched documents will have an additional `_id` field, which is the
document ID. `getDocumentsInCollectionGroup` additionally returns a `_path`
property.
To simply fetch all documents in a collection, use `getDocumentsInCollection`,
e.g.:
```typescript
const collection = await firestore.getDocumentsInCollection("my-collection");
```
If you want to fetch documents from a sub collection (aka. collection group),
you can do so with `getDocumentsInCollectionGroup`, e.g.:
```typescript
// e.g. `my-sub-collection` is a sub collection of `my-collection/{someId}`
const collection = await firestore.getDocumentsInCollectionGroup(
"my-sub-collection",
);
```
### Fetch all documents in a collection with a filter
Note: The fetched documents will have an additional `_id` field, which is the
document ID.
> You can use the same syntax for both `getDocumentsInCollection` and
> `getDocumentsInCollectionGroup` methods. The latter also returns a `_path`
> property.
```typescript
// Import the FirestoreOperator enum
import { FirestoreOperator } from "@koiztech/firestore-admin";
// e.g.
const documents = await firestore.getDocumentsInCollection("my-collection", {
where: {
filters: [
["name", FirestoreOperator.EQUAL, "John Doe"],
],
},
});
// e.g.
const document = await firestore.getDocument("my-collection", {
where: {
filters: [
["name", FirestoreOperator.IN, ["John Doe", "Max Mustermann"]], // example of an IN filter
],
},
});
// e.g. a more complex query
const documents = await firestore.getDocumentsInCollection("my-collection", {
where: {
filters: [
["name", FirestoreOperator.EQUAL, "Ivan Petrov"],
["height", FirestoreOperator.LESS_THAN, 200],
["address.city", FirestoreOperator.EQUAL, "Moscow"], // example of a nested field
[
"bornAt",
FirestoreOperator.GREATER_THAN,
new Date("1990-01-01T12:50:00.000Z"),
], // example of a timestamp filter
],
},
orderBy: [{ field: "createdAt", direction: "DESCENDING" }], // you can sort the results
limit: 3, // you can limit the number of results
});
```
### Fetch a specific document
```typescript
const document = await firestore.getDocument("my-collection/my-document");
```
### Update a document
```typescript
await firestore.updateDocument("my-collection/my-document", {
name: "John Doe",
});
// ...or with specific update fields
await firestore.updateDocument("my-collection/my-document", {
name: "John Doe",
age: 30, // this field will not be updated
address: {
city: "Dubai",
country: "United Arab Emirates", // this field will not be updated
},
}, ["name", "address.city"]); // you can use nested fields as well
```
Returns the updated document with an additional `_id` and `_path` fields.
## Using timestamps
If you need to use Firestore timestamps, simply use `Date` objects, e.g.:
```typescript
const now = new Date();
// ...and then use it in your document:
await firestore.createDocument("my-collection", {
createdAt: now,
});
```
The above `Date` object will be converted to a Firestore timestamp
automatically.
When filtering results by timestamp, make sure to use `Date` objects as well,
e.g.:
```typescript
const documents = await firestore.getDocumentsInCollection("my-collection", {
where: {
filters: [[
"createdAt",
FirestoreOperator.GREATER_THAN,
new Date("2024-12-02"),
]],
},
});
```
In the query results, timestamp fields will be returned as an ISO Date string,
e.g. `2025-01-01T00:00:00.000Z`.
## Using document IDs in a filter
If you need to filter query results by document IDs in the
`getDocumentsInCollection` method, you can do so with the `documentId` field.
For example:
```typescript
// Will return all documents in the collection with the document IDs `docId1` and `docId2`.
const documents = await firestore.getDocumentsInCollection("my-collection", {
where: {
filters: [["documentId", FirestoreOperator.IN, ["docId1", "docId2"]]],
},
});
// You can still combine it with other filters, e.g.:
const documents = await firestore.getDocumentsInCollection("my-collection", {
where: {
filters: [
["documentId", FirestoreOperator.IN, ["docId1", "docId2"]],
["isActive", FirestoreOperator.EQUAL, true],
],
},
});
```