0

使用 Swift 代码 5.1,我设法使用当前用户购物篮中的项目更新 Firestore 数据库,但无法添加/更新数量。目前,如果我想添加一个已经存在于购物篮中的项目,它只需添加另一行,但我只想更新数量。

你能告诉我如何创建一个增加数量的函数吗?

这是我到目前为止的代码。只粘贴了相关的代码部分。

我的 Helper 文件中的 Firestore DB 函数:

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

}

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

}

这是我的篮子模型文件中的代码

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(_篮子:篮子,withValues:[String:Any],完成:@escaping(_错误:错误?)-> Void){ FirebaseReference(.Basket).document(basket.id).updateData(withValues){ (错误)完成中(错误)

项目视图控件中用于将项目添加到购物篮的代码:

    @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)
        }

    }

}

为了澄清我的请求,我需要在我的编码中更改/重新安排什么,以便数据库云 Firestore 按我所附屏幕截图中显示的顺序排列。第一个屏幕截图显示了最后一列中的当前布局,我正在尝试将其更改为第二个屏幕截图中显示的布局?

在此处输入图像描述

4

2 回答 2

1

我想您是在问如何更新 Firestore 文档中某个字段的值。如果没有,请告诉我,我会更新答案。

这是一些更新库存中物品数量的代码。传入数量以添加为 + Int,然后作为 - Int 减去。结构看起来像这样

root
   inventory
      item_0
         qty: 0

并且更新 qty 节点的代码是:

func incrementQty(deltaQty: Int) {
    let docToUpdate = self.db.collection("inventory").document("item_0")

    docToUpdate.updateData( [
        "qty": FieldValue.increment( Int64(deltaQty) )
    ])
}

像这样称呼它

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

以前,必须将递增值包装到事务中以使其安全,但FieldValue使它更容易。

于 2020-01-21T18:13:51.413 回答
0

我正在根据评论和问题澄清添加另一个答案。我的另一个答案仍然是一个答案,但它是一种不同的方法。

数组本质上很难在 NoSQL 数据库中使用,因为它们通常被视为单个对象。与集合、文档和字段相反,它们的功能有限,并且不能直接排序或插入项目。查询很好,很有挑战性。Firestore 在提供与阵列更好的互操作性方面做得很好,但通常仍然有更好的选择。

而不是一个数组,我会将结构更改为:

Baskets                (collection)
   basket_number       (document in the Baskets collection, like you have now)
      items            //a collection of items in the basket
         item_0        //a document with the docID being the the item number
            item_qty:  //qty of the item
         item_1
            item_qty:
         item_2
            item_qty:

所以 .updateData 的缺点是,如果被更新的字段不存在,它不会创建该字段,它只会抛出一个错误。所以我们需要先测试该文档是否存在,如果存在,则使用updateData进行更新,如果不存在,则使用初始数量创建项目。

这是执行此操作的代码 - 请注意,为简单起见,我忽略了顶层 Basket 和 basket_number,因为您已经知道如何执行该部分并专注于项目收集和向下。

func incrementQty(itemNumberToUpdate: String, deltaQty: Int) {
    let docToUpdate = self.db.collection("items").document(itemNumberToUpdate)
    docToUpdate.getDocument(completion: { documentSnapshot, error in
        if let err = error {
            print(err.localizedDescription)
            return
        }

        if let _ = documentSnapshot?.data() {
            print("item exists, update qty")
            docToUpdate.updateData([
                "item_qty": FieldValue.increment( Int64(deltaQty) )
            ], completion: { err in
                if let err = err {
                    print("Error updating document: \(err.localizedDescription)")
                } else {
                    print("Item qty successfully updated")
                }
            })
        } else {
            print("no item exists, need to create")
            docToUpdate.setData([
                "item_qty": FieldValue.increment( Int64(deltaQty) )
            ], completion: { err in
                if let err = err {
                    print("Error updating document: \(err.localizedDescription)")
                } else {
                    print("Item successfully created with initial quantity")
                }
            })
        }
    })
}

传入一个项目编号和数量来修改现有数量,或者将是初始数量。

self.incrementQty(itemNumberToUpdate: "item_0", deltaQty: 5)
于 2020-01-22T22:03:25.790 回答