使用Firebase将值与值数组进行比较。迅速

时间:2018-01-09 10:16:44

标签: ios swift firebase firebase-realtime-database

我有一个值需要与一组值进行比较。基本上,用户需要检查它是否与另一个用户具有相同的项目。但我正在努力解决这个问题,因为我如何获得一组用户的项目?通常,当您观察到某个值时,您会执行以下操作:

Database.database().reference(withPath: "users/\(userID)/itemList").observeSingleEvent...

然而,当涉及到用户数组时,如果有多个ID,如何实现这一目标呢?我想将一个或多个用户项目与其他用户项目进行比较,并检查它们是否匹配,以便对具有匹配项的用户数组进行排序。

如果已经有一个例子,请帮助指导我。

更新

这是我的数据结构的外观:

{
  "users": {
    "EWJGFYmVTzOiHgnq42ebhrg2fj": {
      "firstName": "Friederike",
      "itemList": [
        2: true,
        3: true,
        0: true
      ]
    },

    "C076OYmVTzOiHgnq4wPQtY2XpED2": {
      "firstName": "Ian",
      "itemList": [
        0: true,
        1: true,
        3: true
      ]
    },
    "Juoiuf0N6qNmkm32jrtu6X6UK62": {
      "itemList": [
        0: true
      ],
      "firstName": "Jack"
    }
  }
}

更新2.0

通过下面的答案,我可以通过items表查询,但仍然无法查询匹配的键,因为可能有多个数组,因此我无法使用它来过滤或任何事情。

1 个答案:

答案 0 :(得分:1)

好的,使用您当前的数据结构,您必须查询用户下的所有节点,然后比较数组,这是非常低效的。在不修改结构的情况下,没有直接或简单的方法可以做到这一点。因此,我建议您修改数据结构,以便每个项目都包含拥有它的所有用户的列表。像这样:

{
  "items": {
    "0": {
      "EWJGFYmVTzOiHgnq42ebhrg2fj": "Friederike",
      "C076OYmVTzOiHgnq4wPQtY2XpED2": "Ian",
      "Juoiuf0N6qNmkm32jrtu6X6UK62": "Jack"
    },

    "1": {
      "C076OYmVTzOiHgnq4wPQtY2XpED2": "Ian"
    },

    "2": {
      "EWJGFYmVTzOiHgnq42ebhrg2fj": "Friederike"
    }
    //....
  }
}

根据您要显示的内容,您可能希望存储的信息不仅仅是用户UID和用户名。您可以使用如下查询查询与您具有相同项目的所有用户:

let ref = Database.database().reference()
// assuming you already have the current users items stored in an array
for item in items {
    ref.child("items").child(String(item)).observeSingleEvent(of: .value, with: { snap in
        for child in snap.children {
            let child = child as? DataSnapshot
            if let key = child?.key, let name = child?.value as? String {
                // do something with this data
            }
        }
    })
}

Firebase数据库是noSQL,因此数据应为denormalized或重复,以便可以优化查询。 Firebase实际上建议您避免使用nesting data。有关详细信息,请查看此question

希望有所帮助

与评论中提出的问题相关的代码

假设您要存储字符串数组中具有相同项目的用户的UID或名称,您可以prevent duplicates使用.contains()

var namesWithMatchingItems = [String]()

if !namesWithMatchingItems.contains(nameYouJustFetched) {
    namesWithMatchingItems.append(nameYouJustFetched)
}