简体   繁体   中英

Using Swift to Decode Firebase Dictionary as Array

I am trying to decode data from my realtime database using codable structs in Swift, but am stuck trying to decode a dictionary with an array but I do not know how to make this right. I want the usedBy dictionary decoded but cannot figure out how.

Here is the data in firebase:

{
  "active": 1,
  "code": "FELLA",
  "owner": 33206,
  "percent": 50,
  "usedBy": {
    "-N5lHtnKtAiBWrQMxW0a": {
      "amount": 1000,
      "date": "2022-06-29 21:08:51 +0000",
      "paid": false,
      "userid": 33206
    },
    "-N6L0vybeecuu175FV-4": {
      "amount": 5000,
      "date": "2022-07-07 00:20:41 +0000",
      "paid": false,
      "userid": 33206
    },
    "-N6L0w5WVS6mkVGrfJMW": {
      "amount": 5000,
      "date": "2022-07-07 00:20:41 +0000",
      "paid": false,
      "userid": 33206
    },
    "-N6L190TsMr6OJAXod1G": {
      "amount": 1000,
      "date": "2022-07-07 00:21:38 +0000",
      "paid": false,
      "userid": 33206
    }
  }
}

Data models:

struct PromoCode: Codable {
    var active: Int
    var amount: Int?
    var code: String
    var percent: Int?
    var owner: Int?
    var usedBy: [PromoCodeUsed]?
}

struct PromoCodeUsed: Codable {
    var amount: Int
    var date: String
    var paid: Bool
    var userid: Int
}

Code:

func getPromoCodeInfo(handler: @escaping (PromoCode?) -> ()) {
    guard let userid = AuthService.shared.userID else { return }
    promoCodes.queryOrdered(byChild: "owner").queryEqual(toValue: userid).observeSingleEvent(of: .value) { snapshot in
        
        
        for child in snapshot.children {
            guard let snap = child as? DataSnapshot else { return }
            guard let value = snap.value as? [String: Any] else { return }
            do {
                let jsonData = try JSONSerialization.data(withJSONObject: value, options: [])
                let decoded = try JSONDecoder().decode(PromoCode.self, from: jsonData)
                handler(decoded)
            } catch {
                print("ERROR HERE: \(error)")
            }
        }
    }
}

Error message:

ERROR HERE: typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "usedBy", intValue: nil)], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))

How can I fix my this so that I can decode the usedBy dictionary as an array of PromoCodeUsed Objects?

The model you are using is wrong, it should be like this :

struct PromoCode: Codable {
    let active: Int?
    let code: String?
    let owner, percent: Int?
    let usedBy: [String: PromoCodeUsed]?
}


struct PromoCodeUsed: Codable {
    let amount: Int?
    let date: String?
    let paid: Bool?
    let userid: Int?
}

and then need to update getPromoCode function implementation according to that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM