Быстрый код для добавления товара с количеством в базе данных Firebase - PullRequest
0 голосов
/ 21 января 2020

Используя код Swift 5.1 Мне удалось обновить базу данных Firestore, добавив элементы в текущую корзину пользователей, но не смог добавить / обновить количество. В настоящее время, если я хочу добавить товар, который уже существует в корзине, он просто добавляет другую строку, но я хотел просто обновить количество.

Можете ли вы посоветовать мне, как создать функцию, которая добавляет количество?

Вот коды, которые у меня есть. Вставлены только соответствующие разделы кода.

Функция базы данных Firestore в моем файле Helper:

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

fun c updateBasketInFirestore (_ basket: Basket, withValues: [String: Any], завершение: @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)
        }

    }

}

Чтобы уточнить мой запрос, что мне нужно изменить / переставить мою кодировку так, чтобы хранилище баз данных Cloud Cloud было расположено в порядке, показанном на прикрепленном снимке экрана. Первый снимок экрана с текущим макетом в последнем столбце, и я пытаюсь изменить его на макет, показанный на втором снимке экрана?

enter image description here

Ответы [ 2 ]

1 голос
/ 21 января 2020

Я думаю, вы спрашиваете, как обновить значение в поле в документе 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 делает это намного проще.

0 голосов
/ 23 января 2020

Я добавляю еще один ответ на основе комментариев и уточнения вопроса. Мой другой ответ до сих пор остается ответом, но это другой подход.

С массивами по сути сложно работать в базах данных No SQL, поскольку они часто рассматриваются как один объект. Они имеют ограниченную функциональность в отличие от коллекций, документов и полей и не могут быть отсортированы напрямую или иметь вставленные элементы. И запросы это хорошо, сложно. 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, если не создать элемент с начальным количеством.

Вот код, который делает это - обратите внимание, для простоты я игнорирую top level 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...