使用Swift解码实时数据库响应

发布于 2025-02-13 20:43:58 字数 2320 浏览 0 评论 0 原文

我正在尝试解码Firebase实时数据库响应,但遇到解码错误,我认为这不是我的结构是问题所在,但我不知道我要去哪里做错了,我在做什么错?

现在的问题似乎是 promocodused 是字典而不是数组

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

代码:

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

datamodel

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: Int
    var userid: Int
}

数据

{
  "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
    }
  }
}

I am trying to decode a firebase realtime database response but running into a decoding error, I do not think it's my structs that are the problem but I do not know where I am going wrong, what am I doing wrong?

The issue now seems to be with PromoCodeUsed Being a dictionary instead of an array

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

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

dataModel

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: Int
    var userid: Int
}

Data

{
  "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
    }
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自此以后,行同陌路 2025-02-20 20:43:58

当您针对Firebase数据库执行查询时,可能会有多个结果。因此,快照包含这些结果的列表。即使只有一个结果,快照也将包含一个结果的列表。

您的代码需要处理此列表,但没有这样做。处理列表的最简单方法是您得到了,请循环过 snapshot.Children ,然后将每个单独的孩子快照转换为 promocode 对象。

When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.

Your code needs to handle this list, but fails to do so. The easiest way to handle the list is to loop over the children of the snapshot you get, so loop over snapshot.children and then convert each individual child snapshot to a PromoCode object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文