Search for sub child in firebase database

≡放荡痞女 提交于 2020-01-17 08:19:09

问题


Firebase Structure

Hi, I am try to work out how to query jobBrand & jobName in my Firebase Database (Structure Attached) and store it in a tableView. I am going to store more information under each Job Brand so I would like to keep the structure this way if possible?

So far, I can get tableView to read the 2 fields if they are one level up, so the structure would be:

tbaShootApp -> Jobs -> Job Brand > data.

I cannot work out to query down another level and store it in the tableView. Is this possible?

I am using a dictionary to store the job information:

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
}

}

Here is the code to query the data - I have the function 'fetchJobs' in my superViewDidLoad.

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

回答1:


UPDATE

Since you have added a lot more information since I posted my answer. It is now obvious that you want to query deeper. Additionally, since you posted the actual JSON it is now obvious that the JobBrand node is dynamic. You can query one level below an unknown child. You can read about that here.

I'm going to change .observe(.childAdded) to .observeSingleEvent(of: .value) because you are querying so deep I doubt you want to observe that node, but I could be wrong. Changing this will pull the data in once and only once. If you want to update that value you will have to query again.

You want a query like this:

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

ORIGINAL ANSWER

You current query is going to return all of the data under jobs. Which includes the nodes Job Brand -> jobinfo -> etc.

If you are trying to get less data then you need to know either the JobBrand, jobinfo or both. However, I think you want all of the jobs and your query just isn't working.

You current query fails because your dictionary contains everything under "Jobs" not just one job. You want to loop over the data snapshot and get each job before you call 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 provides this example for looping over a snapshot

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



回答2:


There's a long way to go but maybe this will help:

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

It will let you know each time a new Jobs is added (Candycrush, Honda etc).

(Note - apart from anything else, you very likely also want to observe removals on that list, also.)

If you are making a table (or whatever ... some sort of list, paging thing, collection of tabs, or the like):

almost certainly each row of the table will, on it's own, want to observe that job.

So the first row, would observe for changes in Jobs/Candycrush

So the second row, would observe for changes in Jobs/Honda

And so on. Each table row (or screen, panel, bubble, tab, or whatever it is) would, on it's own, observe that thing.

Incidentally, almost certainly the "first level" header there (where you have Honda, Candycrush etc) would be an id string. (Just use a UUID, or let Firebase do it.) And then a field "Title" would be Honda etc. It would be very unusual to use the actual title as the sort of ID there. (Note that, apart from anything else, you then can't change/edit the title!).



来源:https://stackoverflow.com/questions/47940703/search-for-sub-child-in-firebase-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!