//1. retrieve specific id and store in array

let uid = Auth.auth().currentUser?.uid
        Database.database().reference().child("users").child(uid!).child("cart").observeSingleEvent(of: .value, with: { (snapshot) in


        if let snapDict = snapshot.value as? [String:AnyObject]{

            for each in snapDict as [String:AnyObject]{

                let refID = each.value["refID"] as! String
                self.ArrproductID.append(refID) //append to array

            }
             //print(self.ArrproductID)
        }

    })
    { (error) in
        print(error.localizedDescription)
    }

//2. retrieve data from firebase based on the id stored in array

    refProduct = (Database.database().reference().child("Product").queryOrderedByKey().queryEqual(toValue: ArrproductID) as! DatabaseReference)

    refProduct.observe(DataEventType.value, with:{(snapshot) in
        if snapshot.childrenCount>0{
            self.productList.removeAll()

            for Product in snapshot.children.allObjects as![DataSnapshot]{

                let productObject = Product.value as? [String: AnyObject]
                let ID = Product.key
                let ProductName = productObject?["ProductName"]
                let ProductPrice = productObject?["ProductPrice"]
                let ProductImage = productObject?["ProductImage"]



                //refer to the productmodel.swift? //2. store into model?
                let product = ProductModel( ProductId: ID as String?, ProductName: ProductName as! String? , ProductPrice: ProductPrice as! String?, ProductImage: ProductImage as! String?)


                //3. apend all product to list
                self.productList.append(product)



            }
            //reload all the data?
            self.CartItemView?.reloadData()


        }
    })

1 Answers

0
Jay On

The question is a bit vague but I think you are trying to load specific products based on ID's (keys) stored in an array?

If so, you can't do that directly

This

.queryEqual(toValue: ArrproductID)

will not work as ArrproductID is an array and .queryEqual only excepts a single value.

Firebase Realtime Database doesn't have an 'IN' query. To accomplish this, you'll need to iterate over each value in the array and retrieve the product.

Assuming your structure looks like this

Products
   product_0
      ProductName: "Shampoo"
      ProductPrice: "$1.99"
      ProductImage: "some url"
   product_7
      ProductName: "Milk"
      ProductPrice: "$2.99"
      ProductImage: "another url"

and then the code to read specific products stored in an array

func getProducts() {
    let productArray = ["product_0", "product_7"]
    let productsRef = self.ref.child("Products")

    for productId in productArray {
        let thisProductRef = productsRef.child(productId)
        thisProductRef.observeSingleEvent(of: .value, with: { snapshot in
            let name = snapshot.childSnapshot(forPath: "ProductName").value as? String ?? "No Name"
            let price = snapshot.childSnapshot(forPath: "ProductPrice").value as? String ?? "$0.00"
            let image = snapshot.childSnapshot(forPath: "ProductImage").value as? String ?? "No Image"
            print(name, price, image)
        })
    }
}

and the output is

Shampoo $1.99 some url
Milk $2.99 another url

Keep in mind that Firebase generally doesn't recommend iterating over observes in a tight loop. That may block the main thread and prevent closures from updating the UI. If it's a small dataset then it should not be an issue.

If it's a larger dataset, here may be better ways to structure your data to get the results you want. For example, if you want to get all hair care products, adding a field to the each child like 'ProductCategory' with a value of 'Hair Care' would then enable you to easily query the Products node for all Hair Care products.