Firestore: Multiple conditional where clauses

Firebase Version 9

The docs do not cover this but here is how to add conditional where clauses to a query

import { collection, query, where } from 'firebase/firestore'

const queryConstraints = []
if (group != null) queryConstraints.push(where('group', '==', group))
if (pro != null) queryConstraints.push(where('pro', '==', pro))
const q = query(collection(db, 'videos'), ...queryConstraints)

The source of this answer is a bit of intuitive guesswork and help from my best friend J-E^S^-U-S


As you can see in the API docs, the collection() method returns a CollectionReference. CollectionReference extends Query, and Query objects are immutable. Query.where() and Query.orderBy() return new Query objects that add operations on top of the original Query (which remains unmodified). You will have to write code to remember these new Query objects so you can continue to chain calls with them. So, you can rewrite your code like this:

var query = firebase.firestore().collection("book")
query = query.where(...)
query = query.where(...)
query = query.where(...)
query = query.orderBy(...)
query.get().then(...)

Now you can put in conditionals to figure out which filters you want to apply at each stage. Just reassign query with each newly added filter.

if (some_condition) {
    query = query.where(...)
}

With Firebase Version 9 (Jan, 2022 Update):

You can filter data with multiple where clauses:

import { query, collection, where, getDocs } from "firebase/firestore";

const q = query(
  collection(db, "products"),
  where("category", "==", "Computer"),
  where("types", "array-contains", ['Laptop', 'Lenovo', 'Intel']),
  where("price", "<=", 1000),
);

const docsSnap = await getDocs(q);
    
docsSnap.forEach((doc) => {
  console.log(doc.data());
});