I have nested an object inside my Firestore objects and am trying to filter based on it ..but it returns no object. here is what my nested objects look like :
Now in my function whenever I do something like
query = query.where('country.object_id', '==', req.query.country);
here is the function am using to get that data :
/**
* Import function triggers from their respective submodules:
*
* const {onCall} = require("firebase-functions/v2/https");
* const {onDocumentWritten} = require("firebase-functions/v2/firestore");
*
* See a full list of supported triggers at https://firebase.google.com/docs/functions
*/
const {onRequest} = require("firebase-functions/v2/https");
const logger = require("firebase-functions/logger");
// Create and deploy your first functions
// https://firebase.google.com/docs/functions/get-started
// exports.helloWorld = onRequest((request, response) => {
// logger.info("Hello logs!", {structuredData: true});
// response.send("Hello from Firebase!");
// });
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
exports.getFilteredProperties = functions.https.onRequest(async (req, res) => {
try {
let query = db.collection('properties');
if (req.query.country) {
query = query.where('country.object_id', '==', req.query.country);
}
if (req.query.city) {
query = query.where('city.object_id', '==', req.query.city);
}
if (req.query.level_1) {
query = query.where('level_1.object_id', '==', req.query.level_1);
}
if (req.query.level_2) {
query = query.where('level_2.object_id', '==', req.query.level_2);
}
if (req.query.level_3) {
query = query.where('level_3.object_id', '==', req.query.level_3);
}
if (req.query.level_4) {
query = query.where('level_4.object_id', '==', req.query.level_4);
}
if (req.query.level_5) {
query = query.where('level_5.object_id', '==', req.query.level_5);
}
if (req.query.level_6) {
query = query.where('level_6.object_id', '==', req.query.level_6);
}
if (req.query.level_7) {
query = query.where('level_7.object_id', '==', req.query.level_7);
}
if (req.query.operationType) {
query = query.where('type.id', '==', req.query.operationType);
}
if (req.query.propertyType) {
query = query.where('propertyType.id', '==', req.query.propertyType);
}
if (req.query.minPrice) {
query = query.where('price', '>=', Number(req.query.minPrice));
}
if (req.query.maxPrice) {
query = query.where('price', '<=', Number(req.query.maxPrice));
}
const snapshot = await query.get();
if (snapshot.empty) {
res.status(404).send('No matching documents.');
return;
}
let properties = [];
snapshot.forEach(doc => {
let data = doc.data();
properties.push({
mainImage: data.country,
mainImage: data.mainImage,
propertyType: data.propertyType,
type: data.type,
price: data.price,
title: data.title,
address: data.address,
city: data.city,
bedrooms: data.bedrooms,
bathrooms: data.bathrooms,
area: data.area
});
});
res.status(200).json(properties);
} catch (error) {
console.error("Error fetching properties: ", error);
res.status(500).send(error);
}
});
direct filters work fine like :
query = query.where('price', '>=', Number(req.query.minPrice));
but filtering based on a nested object fails.
query = query.where('city.object_id', '==', req.query.city);
The syntax you're using for querying nested properties is correct, but you're passing req.query.country
. Since query parameter are always a string and object_id
is a number in the database, those values will never match.
So convert req.query.country
to a number (with parseInt
) and pass that value into the query.