Как я могу вызвать обработчик завершения только после того, как данные были установлены? - PullRequest
0 голосов
/ 27 марта 2019

Представленная ниже функция, по-видимому, доставляет orderId через обработчик завершения до того, как данные были заданы в firebase, что приводит к сбою внутренней функции, использующей orderId для извлечения связанных данных из Firestore. Возможно, что бэкэнд-функция дает сбой по другим причинам, но, вероятно, потому, что функция не завершила установку данных в хранилище данных при доставке orderId. Как мне сделать так, чтобы моя функция доставляла orderId только после того, как данные были установлены?

public func uploadTransactionData(_ menuItems: [MenuItem], tip: Int, tax: Int, rewardAmountApplied: Int, totalPaidFromCredit: Int, discountAmount: Int, subTotal: Int, balanceId: String, locationId: String, completion: @escaping ((String?) -> ())) {
    guard let userId = Auth.auth().currentUser?.uid else { completion(nil); return }
    let utilitiesManager = UtilitiesManager()
    let timestamp = utilitiesManager.timestamp()
    var listOfItems = [Any]()
    for item in menuItems {
        do {
            let jsonData = try JSONEncoder().encode(item)
            let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
            listOfItems.append(jsonObject)
        }
        catch let err {
            print("$-- error uploading transaction data \(err)")
            completion(nil)
            return
        }
    }
    let orderRef = Firestore.firestore().collection("order").document()
    let orderId = orderRef.documentID
    let totalPrice = subTotal + tax + tip + discountAmount
    let params: [String: Any] = ["date": timestamp,
                                "total_amount": totalPrice,
                                "tip_amount": tip,
                                "tax_amount":tax,
                                "discount_amount": discountAmount,
                                "reward_amount": rewardAmountApplied,
                                "balance_amount": totalPaidFromCredit,
                                "balance_id": balanceId,
                                "subtotal": subTotal,
                                "account_id": userId,
                                "location_id": locationId,
                                "status": "PENDING",
                                "notes": "",
                                "line_items": listOfItems
    ]
    orderRef.setData(params)
    { err in
        if let e = err {
            print("$-- error uploading transaction data \(e)")
            completion(nil)
        } else {
            completion(nil)
        }
    }
    completion(orderId)
}

1 Ответ

1 голос
/ 27 марта 2019

setData является асинхронным и возвращается немедленно, прежде чем база данных сгенерирует какие-либо результаты. Вы вызываете завершение () в конце своей функции безоговорочно, прежде чем результаты будут завершены. Возможно, вы хотели сказать что-то вроде этого:

orderRef.setData(params)
{ err in
    if let e = err {
        print("$-- error uploading transaction data \(e)")
        completion(nil)
    } else {
        // Change this line to yield the order id to the callback on success
        completion(orderId)
    }
}
// Remove this line that always calls the completion before the result
// completion(orderId)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...