0

This should be easy and there are a lot of similar questions but nothing works for me.

Firebase Structure

Here is my code and should print a snap shot but doesn't.

  override func viewDidLoad() {
      super.viewDidLoad()


     let Ref = Database.database().reference(withPath: "Exhibitors-List/join").queryOrdered(byChild: "joinID").queryEqual(toValue:"1-22")

    ref.observe(.value, with: {
      snapshot in
      var newItems: [Exhibitors] = []

      for item in snapshot.children{
        print(snapshot.value as Any)
        let joinItem = Exhibitors(snapshot: item as! DataSnapshot)
        newItems.append(joinItem)
      }

      self.items = newItems
      self.tableView.reloadData()

    })
  }

I have no problem getting a snapshot when searching one child up in idComp or boothLocation but not in joinID, so is it my code or is my Firebase structure off?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

3 Answers3

1

When you run a query at a location, Firebase checks every child of that location for the property that you order on. There is no data in Exhibitors-List/join, so the query gives no results.

Instead what you want to do is run a query on Exhibitors-List and then order/filter on join/joinID/0:

 let Ref = Database.database().reference(withPath: "Exhibitors-List/join").queryOrdered(byChild: "joinID/0").queryEqual(toValue:"1-22")

This would work, but only if you have the joinId you want in index 0.

What you're essentially trying to do is a reverse lookup here. Your current data structure is good for finding the join IDs for a given exhibitor. It is not good for finding the existing exhibitors for a join ID. To allow that efficiently, you need to create an additional data structure:

joinIds: {
  joinId1: {
    exhibitorId1: true,
    exhibitorId2: true
  },
  joinId2: {
    exhibitorId2: true
  }
}

With this additional structure you can look up the exhibitor IDs quickly from /joinIds/1-22.

Also see my explanation here: Firebase query if child of child contains a value

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Hello got side tracked on other work, Excellent answers gentlemen. You sowed me both that my database structure was off and my search was off for a child. Using your advice I solved my problem. I will ellaborate for future viewers and yourselves as experts . First let me address Franks suggestion to create an additional data structure. I did have an existing data structure see https://manufacturing.show/delmar/FireBaseJoin.png, however Google said "Read Only mode activated" on the Join-List structure shown above, I felt since there are over 40K joins my JSON tree was inefficient c next com – Douglas Bodenstab Mar 08 '18 at 19:36
  • The join represents an exhibitors Categories and subcategories. So I came up with scheme that we discussed a few days ago. Now I made it work using your answers. New Structure see https://manufacturing.show/delmar/FireBaseExList.png. and new swift code that works thanks to your help ........ let textj = "join/" let text = textj + detailNamer! print ("in exsubvie detail Name \(text).") let Ref = Database.database().reference(withPath: "Exhibitors-List").queryOrdered(byChild:text).queryEqual(toValue:1) Ref.observe(.value, with: { snapshot in – Douglas Bodenstab Mar 08 '18 at 19:41
  • detailNamer is a variable such as "1-22" that comes from a previous table view. – Douglas Bodenstab Mar 08 '18 at 19:48
0

Your code is asking to query the location Exhibitors-List/join, but that location doesn't exist in your database. As far as I can see, there is another node 0 that sits between Exhibitors-List and the nearest join child. You can't skip elements when querying - you need to query at a path that fully exists.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
0
 override func viewDidLoad() {
   super.viewDidLoad()

   let textj = "join/"
   let text =  textj + detailNamer!


   let Ref = Database.database().reference(withPath: "Exhibitors-   List").queryOrdered(byChild:text).queryEqual(toValue:1)

Ref.observe(.value, with: {
  snapshot in
  var newItems: [Exhibitors] = []

  for item in snapshot.children{
    print(snapshot.value as Any)
    let joinItem = Exhibitors(snapshot: item as! DataSnapshot)
    newItems.append(joinItem)
  }

  self.items = newItems
  self.tableView.reloadData()

})

}