Swift 用于在 Firebase 数据库中添加带有数量的项目的代码
Swift code to Add item with quantity in Firebase Database
使用 Swift 代码 5.1 我已设法使用当前用户购物篮中的项目更新 Firestore 数据库,但无法达到 add/update 数量。目前,如果我想添加一个已经存在于购物篮中的项目,它只需添加另一行,但我只想更新数量。
你能告诉我如何创建一个添加数量的函数吗?
这是我目前拥有的代码。仅粘贴了相关代码部分。
我的帮助文件中的 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(_ basket: Basket, withValues: [String : Any], completion: @escaping (_ error: Error?) -> 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)
}
}
}
为了阐明我的请求,我需要在编码中 change/re-arrange 做什么,以便数据库云 Firestore 按我所附屏幕截图中显示的顺序排列。第一个屏幕截图在最后一列中显示当前布局,我正在尝试将其更改为第二个屏幕截图中展示的布局?
我想您是在问如何更新 Firestore 文档中字段中的值。如果没有,请告诉我,我会更新答案。
下面是一些更新库存中商品数量的代码。传入数量以作为 + Int 添加,然后作为 - Int 减去。结构看起来像这样
root
inventory
item_0
qty: 0
更新数量节点的代码是:
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 使它变得更容易。
我正在根据评论和问题澄清添加另一个答案。我的另一个答案仍然是一个答案,但它是一种不同的方法。
在 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_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)
使用 Swift 代码 5.1 我已设法使用当前用户购物篮中的项目更新 Firestore 数据库,但无法达到 add/update 数量。目前,如果我想添加一个已经存在于购物篮中的项目,它只需添加另一行,但我只想更新数量。
你能告诉我如何创建一个添加数量的函数吗?
这是我目前拥有的代码。仅粘贴了相关代码部分。
我的帮助文件中的 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(_ basket: Basket, withValues: [String : Any], completion: @escaping (_ error: Error?) -> 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)
}
}
}
为了阐明我的请求,我需要在编码中 change/re-arrange 做什么,以便数据库云 Firestore 按我所附屏幕截图中显示的顺序排列。第一个屏幕截图在最后一列中显示当前布局,我正在尝试将其更改为第二个屏幕截图中展示的布局?
我想您是在问如何更新 Firestore 文档中字段中的值。如果没有,请告诉我,我会更新答案。
下面是一些更新库存中商品数量的代码。传入数量以作为 + Int 添加,然后作为 - Int 减去。结构看起来像这样
root
inventory
item_0
qty: 0
更新数量节点的代码是:
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 使它变得更容易。
我正在根据评论和问题澄清添加另一个答案。我的另一个答案仍然是一个答案,但它是一种不同的方法。
在 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_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)