Search code examples
firebasefirebase-realtime-databaseappendchildswift5product-quantity

Swift code to Add item with quantity in Firebase Database


Using Swift code 5.1 I have managed to update Firestore Database with items in current users basket but not able to add/update quantity. Currently if I wanted to add an item that already exist in the basket it simply adds another line but I wanted to just update quantity.

Can you advise me on how to create a function that adds quantity?

Here are the codes I have so far. Only relevant sections of code pasted.

Firestore DB function in my Helper file:

enum FCollectionReference: String {
case User
case Category
case Items
case Basket
case Orders

}

func FirebaseReference(_ collectionReference: FCollectionReference) -> CollectionReference {
return Firestore.firestore().collection(collectionReference.rawValue)

}

Here's the code in in my Basket Model file using

class Basket {

var id: String!
var ownerId: String!
var itemIds: [String]!
var delivery: Float!
var admin: Float!
var quantity: Int!

init() {
}

init(_dictionary: NSDictionary) {
    id = _dictionary[kOBJECTID] as? String
    ownerId = _dictionary[kOWNERID] as? String
    itemIds = _dictionary[kITEMIDS] as? [String]
    delivery = _dictionary[kDELIVERY] as? Float
    admin = _dictionary[kADMIN] as? Float
    quantity = _dictionary[kQUANTITY] as? Int
}

}

//MARK: Helper functions

func basketDictionaryFrom(_ basket: Basket) -> NSDictionary {

return NSDictionary(objects: [basket.id, basket.ownerId, basket.itemIds, basket.quantity], forKeys: [kOBJECTID as NSCopying, kOWNERID as NSCopying, kITEMIDS as NSCopying, kQUANTITY as NSCopying,kDELIVERY as NSCopying, kADMIN as NSCopying])

}

    //MARK: - Update basket

func updateBasketInFirestore(_ basket: Basket, withValues: [String : Any], completion: @escaping (_ error: Error?) -> Void) { FirebaseReference(.Basket).document(basket.id).updateData(withValues) { (error) in completion(error)

Codes in Item View Control to add items to basket:

    @objc func addToBasketButtonPressed() {
    //check if user is logged in or show login view
    if MUser.currentUser() != nil {

        downloadBasketFromFirestore(MUser.currentId()) { (basket) in
            if basket == nil {
                self.createNewBasket()
            }else {
             basket?.itemIds.append(self.item.id) 
                self.updateBasket(basket: basket!, withValues: [kITEMIDS: basket!.itemIds])

            }
        }
    } else {
        showLoginView()

    }
}

    private func updateBasket(basket: Basket, withValues: [String : Any]) {
    updateBasketInFirestore(basket, withValues: withValues) { (error) in

        if error != nil {
            self.hud.textLabel.text = "Error: \(error!.localizedDescription)"
            self.hud.indicatorView = JGProgressHUDErrorIndicatorView()
            self.hud.show(in: self.view)
            self.hud.dismiss(afterDelay: 2.0)

            print("error updating basket", error!.localizedDescription)

        }else {
            self.hud.textLabel.text = "Added to Basket"
            self.hud.indicatorView = JGProgressHUDSuccessIndicatorView()
            self.hud.show(in: self.view)
            self.hud.dismiss(afterDelay: 2.0)
        }

    }

}

To clarify my request, what do I need to change/re-arrange in my coding so the Database Cloud Firestore is arranged in order shown in my attached screen shot. First screen shot showing current layout in the last column and I'm trying to change this to layout demonstrated in the second screen shot?

enter image description here


Solution

  • I think you are asking how to update the value in a field within a Firestore document. If not, let me know and I will update the answer.

    Here's some code that updates the qty of an item in inventory. Pass in the qty to add as a + Int and then to subtract as a - Int. The structure looks like this

    root
       inventory
          item_0
             qty: 0
    

    and the code to update the qty node is:

    func incrementQty(deltaQty: Int) {
        let docToUpdate = self.db.collection("inventory").document("item_0")
    
        docToUpdate.updateData( [
            "qty": FieldValue.increment( Int64(deltaQty) )
        ])
    }
    

    call it like this

    self.incrementQty(deltaQty: 4) //adds 4 to the existing qty
    

    previously, incrementing values had to be wrapped into a transaction to make it safe but the FieldValue makes it much easier.