I want to perform this query in my mobile app, >/collections{users}/{documentId}/ get some user lists who are age between 18 to 25 in Chennai location and to hide some user fields such as "lastActive" before response to client. Note, I don't want use directly to perform the action in client sdk because of security concern like to prevent rate limit, excessive requests made by users. Each response contains 10 user documents and rate limited by 20 requests per user/day. I know firestore didn't have proper way to tract user rate limit on server-side to prevent security issues. Please don't suggest to use separate subcollection to hide private fields. Simply I don't want another document read count.
Question is, I'm little bit confusing which one to choose to implement, Firestore (onCall or http) trigger function request call from firestore client SDK and another one Firestore REST API deployed it on cloud function. Note, both are deployed it on cloud function.
Seems like aren't the same? I have some requirements this functions should handle concurrent requests minimum 3000 requests.
Example code, using Firestore http trigger function.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.getUsers = functions.https.onRequest(async (req, res) => {
try {
const { minAge, maxAge, location } = req.query;
// Retrieve user documents from Firestore based on age and location filters
const usersSnapshot = await admin
.firestore()
.collection('users')
.where('age', '>=', parseInt(minAge))
.where('age', '<=', parseInt(maxAge))
.where('location', '==', location)
.get();
const users = [];
// Iterate through each user document
usersSnapshot.forEach((userDoc) => {
const user = userDoc.data();
// Remove the "lastActive" field from the user data
delete user.lastActive;
users.push(user);
});
res.status(200).json(users);
} catch (error) {
console.error(error);
res.status(500).json({ error: 'An error occurred' });
}
});
Another one, using Firestore REST API deployed it on cloud function
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const fetch = require('node-fetch');
admin.initializeApp();
const app = express();
app.get('/users', async (req, res) => {
try {
const { minAge, maxAge, location } = req.query;
// Make a request to the Firestore REST API to retrieve user documents
const response = await fetch(
`https://firestore.googleapis.com/v1/projects/${process.env.GCLOUD_PROJECT}/databases/(default)/documents/users?filter=age >= ${minAge} && age <= ${maxAge} && location == '${location}'`
);
const data = await response.json();
const users = [];
// Process the response from the Firestore REST API
data.documents.forEach((doc) => {
const user = doc.fields;
// Remove the "lastActive" field from the user data
delete user.lastActive;
users.push(user);
});
res.status(200).json(users);
} catch (error) {
console.error(error);
res.status(500).json({ error: 'An error occurred' });
}
});
exports.getUsers = functions.https.onRequest(app);
Another one, it's similar to Firestore REST API and deployed it on cloud functions
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
admin.initializeApp();
const app = express();
app.get('/users', async (req, res) => {
try {
const { minAge, maxAge, location } = req.query;
// Retrieve user documents from Firestore based on age and location filters
const usersSnapshot = await admin
.firestore()
.collection('users')
.where('age', '>=', parseInt(minAge))
.where('age', '<=', parseInt(maxAge))
.where('location', '==', location)
.get();
const users = [];
// Iterate through each user document
usersSnapshot.forEach((userDoc) => {
const user = userDoc.data();
// Remove the "lastActive" field from the user data
delete user.lastActive;
users.push(user);
});
res.status(200).json(users);
} catch (error) {
console.error(error);
res.status(500).json({ error: 'An error occurred' });
}
});
exports.getUsers = functions.https.onRequest(app);