Search code examples
firebasefirebase-realtime-databasefirebaseui

Query Firebase object where object contains userID


I have a Firebase database containing a product list and each product has a sublist of cart elements. I would like to only receive the product elements containing a cart element with the right userID.

I am using FirebaseUI listadapter. I get all the elements of the product list but i would like to only show the products containing the userID.

Can i delete Views from the ListAdapter? Or can sort by some query?

All ideas to solve the problem are welcome!

EDIT

Here is part of the Product Class.

public class Product implements Serializable{

    private boolean active;

    private ArrayList<Cart> carts;

    private String description;

    private String details;

    private String ean;

    private String id;

    private String image;

    private String name;

    private Float price;

    private ArrayList<ProductPack> productpacks;

    private int stock;

    private int stockavailable;

    private Float tax;

    private String users; 
}

Part of the data stored in firebase:

products
     -KG8O_5iHKWGCBytLtn0
         active: true
         carts
             0
                 amount: 11
                 userID: "google:116879660852602200588"
             1
                 amount: 12
                 userID: "google:116879660852602200589"
         description: ""
         details:  ""
         ean: ""
         id: "-KG8O_5iHKWGCBytLtn0"
         image: "iVBORw0KGgoAAAANSUhEUgAABqsAAAPACAIAAAAt5NQJAAA..."
         name: "test"
         price: 1
         stock: 0
         stockavailable: 0
         tax: 1
         users: ""
     -KG9-r5ATr1BokkVzuYt
         active: true
         carts
             0
                 amount: 11
                 userID: "google:116879660852602200588"
             1
                 amount: 12
                 userID: "google:116879660852602200589"
         description: ""
         details: ""
         ean: ""
         id: "-KG9-r5ATr1BokkVzuYt"
         image: "iVBORw0KGgoAAAANSUhEUgAABqsAAAPACAIAAAAt5NQJAAA..."
         name: "test"
         price: 1
         stock: 0
         stockavailable: 0
         tax: 0.25
         users: ""

Solution

  • You can tell the Firebase server to filter the data is returns by using a query:

    Firebase ref = new Firebase("https://yours.firebaseio.com");
    Firebase products = ref.child("products");
    Query userProducts = products.orderByChild("userId").equalTo(authData.uid);
    
    FirebaseListAdapter<Product> adapter = new FirebaseListAdapter<Product>(
        this,
        Product.class,
        R.layout.product_layout,
        userProducts
    ) { ...
    

    This is documented in the Firebase documentation on queries, which I highly recommend reading. A few hours spent in the Firebase guide for Android developers, will save you much time down the line.

    A data structure more optimized for this use case

    While this will work, you seem to have applied a SQL-like structure to a NoSQL database. To return the userProducts, the Firebase server will have to consider all products. As the list of products*users grows, this will start taking more and more time.

    A more read-optimized structure takes into account that you typically want to access the products for a user, so it stores the products per user.

    UserProducts
      uid1
        product1: { ... }
        product3: { ... }
        product5: { ... }
      uid2
        product2: { ... }
        product4: { ... }
        product6: { ... }
    

    Now you can access the products for the user:

    Firebase ref = new Firebase("https://yours.firebaseio.com");
    Firebase products = ref.child("UserProducts");
    Firebase userProducts = products.child(authData.uid);
    
    FirebaseListAdapter<Product> adapter = new FirebaseListAdapter<Product>(
        this,
        Product.class,
        R.layout.product_layout,
        userProducts
    ) { ...