CRUD with Cloud Firestore and Node.js by Google Cloud Function
Table of Contents
- Introduction
- Prerequisites
- Setup npm Repository
- Adding Code to Interact with Firestore
- Prepare the CRUD Operations
- Read Data - HTTP GET
- Create Data - HTTP POST
- Update Data - HTTP PUT
- Delete Data - HTTP DELETE
- Complete index.js File
- Deploy to the Cloud
- Conclusion
Introduction
This blog focuses on how to use Google Cloud Functions to handle CRUD operations with Cloud Firestore. Cloud Functions act as the HTTP server, while Firestore serves as the NoSQL database backend. Both services are serverless and hosted in the cloud, so you can focus on your business logic without worrying about server management.
Prerequisites
Before we start, you will need to prepare the following:

- A GCP (Google Cloud Platform) account
- A GCP project set up
- A Firestore collection configured in your GCP project
- A service account with the
Cloud Datastore Ownerrole, with the key file downloaded to your local repository folder
Setup npm Repository
First, initialize the npm repository by running the following command. This will create a package.json file with default settings.
npm init -y
Next, install @google-cloud/functions-framework so you can test the Cloud Function locally.
npm install --save-dev @google-cloud/functions-framework
To test locally, add the following script to your package.json:
"start": "npx functions-framework --target=main [--signature-type=http]"
Also, install the firebase-admin package so you can communicate with Firebase and Firestore.
npm install --save firebase-admin
Adding Code to Interact with Firestore
Once the npm packages are installed, we can start adding code. Create a file called index.js and add the following code to initialize Firestore with the service account credentials.
const { initializeApp, cert } = require("firebase-admin/app");
const { getFirestore } = require("firebase-admin/firestore");
const serviceAccount = require("./service-account-has-fireStore-role.json");
initializeApp({
credential: cert(serviceAccount),
});
Prepare the CRUD Operations
We will create the following basic CRUD operations from the Cloud Function to the Firestore database:
- Read Data - [HTTP GET] -
http://localhost:8080/?docid=800 - Create Data - [HTTP POST] -
http://localhost:8080/
{
"docid": "2000",
"id": "test_10",
"list": [1, 2, 3]
}
- Update Data - [HTTP PUT] -
http://localhost:8080/?docid=800
{
"id": "test_10",
"list": [1, 2, 3]
}
- Delete Data - [HTTP DELETE] -
http://localhost:8080/?docid=800
Read Data - HTTP GET
First, we handle the HTTP GET request for the read operation. Here we check that the HTTP method is GET and that the docid query string parameter is provided.
exports.main = (req, res) => {
if (req.method === 'GET') {
if (!req.query.docid) {
return res.status(404).send('');
}
db.collection('my_collection').doc(req.query.docid.toString()).get()
.then(doc => {
return res.status(200).send(doc.data());
});
}
Below is how it looks when we run npm run start and test with Postman.

Create Data - HTTP POST
For creating data, we expect the HTTP method to be POST and the request body to contain the following JSON structure:
{
"docid": "200",
"id": "test_10",
"list": [10, 20, 30, 40]
}
Once we receive the request.body, we use Firestore's set function to create or update the document in the target collection.
exports.main = (req, res) => {
else if (req.method === 'POST') {
db.collection('my_collection')
.doc(req.body.docid)
.set({
id: req.body.id,
list: req.body.list
})
.then((doc) => {
return res.status(200).send(doc);
});
}
Below is how it looks when we run npm run start and test with Postman.

Update Data - HTTP PUT
For the update operation, we continue using the set function with the document ID passed as a query string parameter.
exports.main = (req, res) => {
else if (req.method === 'PUT') {
db.collection('my_collection')
.doc(req.query.docid)
.set({
id: req.body.id,
list: req.body.list
})
.then((result) => {
return res.status(200).send(result);
});
}
Below is how it looks when we run npm run start and test with Postman.

Delete Data - HTTP DELETE
For the delete operation, we expect the docid to be passed as a query string parameter and use the delete method to remove the document from the Firestore database.
exports.main = (req, res) => {
else if (req.method === 'DELETE') {
db.collection('my_collection')
.doc(req.query.docid).delete()
.then((result) => {
return res.status(200).send(result);
});
}
Below is how it looks when we run npm run start and test with Postman.

The Complete index.js File for CRUD Operations
The following snippet contains all the CRUD code mentioned earlier in a single file.
const {
initializeApp,
applicationDefault,
cert,
} = require("firebase-admin/app");
const {
getFirestore,
Timestamp,
FieldValue,
} = require("firebase-admin/firestore");
const serviceAccount = require("./none-firebase-admin-firm-champion-365105-f0d88d6192e2.json");
initializeApp({
credential: cert(serviceAccount),
});
const db = getFirestore();
exports.main = (req, res) => {
if (req.method === "GET") {
if (!req.query.docid) {
return res.status(404).send("");
}
db.collection("my_collection")
.doc(req.query.docid.toString())
.get()
.then((doc) => {
return res.status(200).send(doc.data());
});
} else if (req.method === "POST") {
db.collection("my_collection")
.doc(req.body.docid)
.set({
id: req.body.id,
list: req.body.list,
})
.then((doc) => {
return res.status(200).send(doc);
});
} else if (req.method === "PUT") {
db.collection("my_collection")
.doc(req.query.docid)
.set({
id: req.body.id,
list: req.body.list,
})
.then((result) => {
return res.status(200).send(result);
});
} else if (req.method === "DELETE") {
db.collection("my_collection")
.doc(req.query.docid)
.delete()
.then((result) => {
return res.status(200).send(result);
});
}
};
Deploy Node.js Code to the Cloud
For deployment, you can use gcloud to deploy from your local machine, integrate with CI/CD, or deploy from a cloud bucket as a zip file. In this example, we will deploy directly from your local folder to the cloud.
Below is the sample command that deploys the function named my-firestore-function to Google Cloud Functions:
gcloud functions deploy my-firestore-function --trigger-http --region=us-central1 --runtime=nodejs16 --gen2 --allow-unauthenticated --entry-point=main
Once the deployment is complete, you should see a URL in the console output. You can also find your Cloud Function URL in the GCP Console. If you browse to the URL with the docid query string parameter, you should see a JSON response from the Firestore database.
Conclusion
This guide demonstrated how to use Google Cloud Functions as an HTTP server to perform CRUD operations with Cloud Firestore as the backend database. Key takeaways:
- Cloud Functions handle HTTP requests (GET, POST, PUT, DELETE) for each CRUD operation
- Firestore's
setmethod can be used for both creating and updating documents - Local testing is possible using the
functions-frameworkbefore deploying to the cloud - Both Cloud Functions and Firestore are serverless, so you can focus on your business logic without managing servers