【问题标题】:Search for sub child in firebase database在 firebase 数据库中搜索子子项
【发布时间】:2018-06-05 01:26:33
【问题描述】:

Firebase 结构

您好,我正在尝试研究如何在我的 Firebase 数据库(附加结构)中查询 jobBrand 和 jobName 并将其存储在 tableView 中。我将在每个工作品牌下存储更多信息,所以如果可能的话,我想保持这种结构吗?

到目前为止,如果它们是上一级的,我可以让 tableView 读取 2 个字段,所以结构是:

tbaShootApp -> 工作 -> 工作品牌 > 数据。

我无法查询下一个级别并将其存储在 tableView 中。这可能吗?

我正在使用字典来存储工作信息:

class Job: NSObject {
var id: String?
var jobBrand: String?
var jobName : String?
var director : String?
var jobInfo : jobInfo?
init(dictionary: [String: AnyObject]) {
    self.id = dictionary["id"] as? String
    self.jobBrand = dictionary["jobBrand"] as? String
    self.jobName = dictionary["jobName"] as? String
    self.director = dictionary["Director"] as? String
}

}

这是查询数据的代码 - 我的 superViewDidLoad 中有函数 'fetchJobs'。

func fetchJobs() {

    Database.database().reference().child("Jobs").observe(.childAdded) { (snapshot) in

        if let dictionary = snapshot.value as? [String: AnyObject] {

                let job = Job(dictionary: dictionary)
                job.id = snapshot.key
                self.jobs.append(job)

                //this will crash because of background thread, use dispatch_async to fix
                DispatchQueue.main.async(execute: {
                    self.tableView.reloadData()
                })
            }
        }
    }

JSON

{
  "Jobs" : {
    "Candycrush" : {
      "cameraInfo" : {
        "cameraBody" : "A",
        "cameraBrand" : "Arri",
        "cameraType" : "Alexa"
      },
      "jobInfo" : {
        "jobBrand" : "CandyCrush",
        "jobName" : "Winter"
      }
    },
    "Honda" : {
      "cameraInfo" : {
        "cameraBody" : "A",
        "cameraBrand" : "Arri",
        "cameraType" : "Alexa XT"
      },
      "jobBrand" : "Honda",
      "jobName" : "Comet"
    },
    "WWF" : {
      "cameraInfo" : {
        "cameraBody" : "A",
        "cameraBrand" : "Red",
        "cameraType" : "Epic"
      },
      "jobInfo" : {
        "jobBrand" : "WWF",
        "jobName" : "Eye"
      }
    }
  }
}

【问题讨论】:

  • 我想我需要更改我的字典设置,以便它看起来正确的孩子,但这是一个完全的猜测?另外,如果这是正确的,我不知道应该是什么?
  • 阅读下层:Database.database().reference().child("Jobs/Job Brand").observe(.childAdded)
  • 感谢 Frank van Puffelen,但“工作品牌”将被用户命名,并且创建的每个“工作品牌”都有不同的名称。所以我不知道每次都叫什么。有没有办法绕过该级别或只查找存在的每个“jobInfo”文件夹?
  • jobInfo 总是同名吗?或者这也是动态的? (提示:提供实际 JSON 的 sn-p 将使这种混淆的可能性大大降低)
  • 您好 Frank van Puffelen,我已将 JSON 附加到帖子中以帮助理解我的数据库。 jobInfo 始终是相同的名称。 jobName 将是动态的级别。

标签: swift uitableview firebase firebase-realtime-database


【解决方案1】:

还有很长的路要走,但也许这会有所帮助:

 .child("Jobs").observe(.childAdded)

每次添加新工作(Candycrush、本田等)时,它都会通知您。

(注意 - 除其他事项外,您很可能还想观察该列表中的删除情况。)

如果您正在制作表格(或其他任何...某种列表、分页、选项卡集合等):

几乎可以肯定表格中的每一行都会单独观察这项工作。

所以第一行会观察Jobs/Candycrush的变化

所以第二行会观察Jobs/Honda的变化

等等。每个表格行(或屏幕、面板、气泡、选项卡或其他任何东西)都会独立观察那个东西。

顺便说一句,几乎可以肯定那里的“第一级”标题(您有 Honda、Candycrush 等)将是一个 id 字符串。 (只需使用 UUID,或者让 Firebase 来做。)然后字段“Title”将是 Honda 等。在此处使用实际标题作为 ID 是非常不寻常的。 (请注意,除此之外,您无法更改/编辑标题!)。

【讨论】:

    【解决方案2】:

    更新

    自从我发布我的答案以来,您已经添加了更多信息。现在很明显,您想要更深入地查询。此外,由于您发布了实际的 JSON,现在很明显 JobBrand 节点是动态的。您可以查询未知孩子的下一级。你可以阅读here

    我要将.observe(.childAdded) 更改为.observeSingleEvent(of: .value),因为您查询的太深了,我怀疑您是否想观察该节点,但我可能错了。更改此设置将只提取一次数据。如果要更新该值,则必须再次查询。

    你想要这样的查询:

    Database.database().reference().child("Jobs").queryOrdered(b‌​yChild: "jobInfo/jobBrand").queryEqual(toValue: "JobBrandYouWant").observeSingleEvent(of: .value, with: { snapshot in
        if let dictionary = snapshot.value as? [String: AnyObject] {
            let job = Job(dictionary: dictionary)
            job.id = snapshot.key
            self.jobs.append(job)
        }
    })
    

    原始答案

    您当前的查询将返回作业下的所有数据。其中包括节点 Job Brand -> jobinfo -> etc.

    如果您想获取更少的数据,那么您需要知道 JobBrand、jobinfo 或两者。但是,我认为您想要所有的工作并且您的查询不起作用。

    您当前的查询失败,因为您的字典包含“工作”下的所有内容,而不仅仅是一项工作。你想循环数据快照和 在调用 init 之前获取每项工作。

    Database.database().reference().child("Jobs").observe(.childAdded, with: { snapshot in 
        for child in snapshot.children { // over over the snapshot and cast each "job" to it's own dictionary
            let child = child as? DataSnapshot
            if let key = child?.key {
                if let dictionary = child?.value as? [String: AnyObject] {
                    let job = Job(dictionary: dictionary)
                    job.id = key
                    self.jobs.append(job)
                }
            }
        }
    })
    

    The documentation 提供了循环快照的示例

    _commentsRef.observe(.value) { snapshot in
      for child in snapshot.children {
        ...
      }
    }
    

    【讨论】:

    • 感谢您回复我。我认为在这个级别的应用程序中,我只想找出 jobBrand 和 jobName。然后当你进入每项工作时,会有更多的信息、附件等。是否值得为这个 tableview 设置一个单独的字典?
    • 如果有帮助,顶层的每个job Brand下面都会有一个jobInfo节点,那么如果我不知道job Brand节点,有没有办法查询jobInfo节点?
    • 是的,你可以这样做。看这个问题stackoverflow.com/questions/40713137/…
    • 太棒了!谢谢@DoesData
    猜你喜欢
    • 2020-07-11
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多