I've been breaking my head thinking about a way to do this so I'll try to be as specific as possible.
I have an application where a user can upload a report of a lost, found or up for adoption pet. The site has to offer the possibility to filter the publications via multiple categories such as 'Category (Lost, Found, Up for adoption), Gender (Female, Male), Animal Type (Dog, Cat, bird, bunny, etc), Hair Type (No hair, short hair, medium hair, long hair), Eyes Type (...,...) and Has collar? (yes, no)
My first approach was to bring all the data from the server and then filter it from the client side but my thesis professor said no because of the amount of data I'm gonna handle. So I must bring the data already filtered from the server side.
So I go and try to make a query that looked like this:
if (activeCategory !== 'All' && activeGender === 'All' && activeAnimal === 'All') {
q = query(
collection(db, "blogs"),
where("category", "==", activeCategory),
where("gender", "!=", activeGender),
where("animal", "!=", activeAnimal),
)
onSnapshot(
q,
async (snapshot) => {
let list = []
snapshot.docs.forEach((doc) => {
list.push({id: doc.id, ...doc.data()})
})
lastDoc = await snapshot.docs[snapshot.docs.length - 1]
firstDoc = await snapshot.docs[0]
list.sort((a, b) => (a.timestamp < b.timestamp) ? 1 : -1)
setBlogs(list)
setFilters(list)
setLoading(false)
setActive("home")
setLastDoc(lastDoc)
setFirstDoc(firstDoc)
}, (error) => {
console.log(error)
}
)
} else if{...} }
useEffect(() => {
fetchData()
}, [activeCategory, activeGender, activeAnimal])
The only way I came up with filtering from server was to make a tremendous amount of if's and this has only 3 categories. If I do all 6 I would need 36 if's (so If you can also think of a way to refactoring is very welcome, but it's not the main point)
What this does basically is to check what checkbox the user chose and set it active and then compare what that says with the data in the database.
So if the user in 'Category' selects 'All' (meaning he wants to see all lost, found and up for adoption pets (no filter on category)) activeCategory = 'All' and it will search all documents in the db that != 'All', resulting in bringing all documents no matter what the category says because they all have either 'Lost' 'Found' or 'Up for adoption' there are none with category: 'All'
So, okay follwoing that logic it should work, but no. Because of firebase's limitations I cannot filter more than one category (two if I have '==' and '!=')
That's where I need your help. How can I filter EVERYTHING from the server side?
I've read about denormalization but I don't know how to apply to my code. And if I'm able to re*estructure my data, how can I create the queries that ask different collections for data?
That's my real question. I can figure out how to re-esructure the data, but can someone write down how the consult would be? How do you 'join' different collections and apply filters on them?
This is how my DB looks in firestore:
Firestore-root
|
--- blogs(collections)
| |
| --- blogId (document)
| |
| --- author: "root root"
| |
| --- breed: ""
| |
| --- category: "adoption"
| |
| --- animal: "rabbit"
|
[...]
And this is how the filters look pic