1

I have a collection called Products and another one named Category.

Products document has a field idCategory, referencing category's id.

I want to get all documents from Products where the category name is equals "Soda".

How can I do that?

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
LMaker
  • 1,444
  • 3
  • 25
  • 38

2 Answers2

2

I want to get all documents from Products where the category name is equals "Soda".

Because you don't have all data in a single document, you need to query your database twice. Once to get the id of the category which is "Soda" in this case and then based on that id get the corresponding products. This is because Firestore doesn't support queries across multiple collections. A single query may only use properties of documents in a single collection.

By why to query the database twice, which is aslo costly when you can query once and get the desired documents. For that, you need to make a little change in your database schema. Since a single product may belong to multiple categories, your new schema should look like this:

Firestore-root
    |
    --- products (collection)
          |
          --- productId (document)
                |
                --- productName: "Soda Water"
                |
                --- category: ["Soda", "Other Category"]
                |
                --- //Other properties

To get all document that are apart of Soda category, please use the following lines of code:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference productsRef = rootRef.collection("products");
Query query = productsRef.whereArrayContains("category", "Soda");

Edit: You can also hold references instead of only ids but for that, please see my answer from this post.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • unfortunately, change the db is not possible at this case :/ – LMaker Dec 21 '18 at 19:03
  • In that case you should query the database twice. But remember, in Firestore everything it's about the number of read an writes. See [here](https://firebase.google.com/docs/firestore/pricing) more informations. So your app will spent a bigger number of read operations than needed and this will cost you more. – Alex Mamo Dec 21 '18 at 19:06
  • I’m sorry if its a stupid question but, what happens when I use `.collection(“Category”).document(“Soda”).collection(“Products”)`? – LMaker Dec 21 '18 at 20:29
  • 1
    You are looking for all documents within the `Products` subcollection. – Alex Mamo Dec 21 '18 at 20:30
0

It looks like you would do a simple query (Firebase Docs Reference):

FirebaseFirestore db = FirebaseFirestore.getInstance();

CollectionReference productsRef = db.collection("Products");

Query query = productsRef.whereEqualTo("idCategory", "Soda");

query.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
    @Override
    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
        /// do things with response
    }
})
.addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        /// do things with error
    });
AnxGotta
  • 1,006
  • 7
  • 28
  • not possible because `Soda` is not the id attributte for Category – LMaker Dec 21 '18 at 19:02
  • Ah! I suppose I misunderstood your nosql structure. I'm glad you found a solution. Alex gave a good clarification of your structure. Your statement "I want to get all documents from Products where the category name is equals "Soda"." indicated that "Soda" was a part of the Product doc with a variable name of category. – AnxGotta Dec 22 '18 at 01:31