0

I'm fairly new to Firebase and have a rankings app, where my structure currently looks like the following:

{
  "Rankings" : {
    "-KFGX5H3rLSnpPvupakm" : {
      "Sports Teams" : {
        "Red sox" : 1,
        "Warriors" : 3,
        "Yankees" : 2
      }
    },
    "-KFGZkwAIl817CLDLmMp" : {
      "Beers" : {
        "Bud light" : 3,
        "Coors" : 2,
        "Pbr" : 4
      }
    }
  }
}

I'm using childIDs so I can sort these chronologically. If I want to search rankings by name, how can I bypass the child ID to do so?

For instance, if a user searches for rankings using the term "Sports," how can I traverse my Rankings tree by searching for all rankings containing "Sports"?

slider
  • 2,736
  • 4
  • 33
  • 69
  • You've included a picture of the JSON tree in your question. Please replace that with the actual JSON as text, which you can easily get by clicking the Export button in your Firebase database. Having the JSON as text makes it searchable, allows us to easily use it to test with your actual data and use it in our answer and in general is just a Good Thing to do. – Frank van Puffelen Apr 13 '16 at 22:03
  • Apologies @FrankvanPuffelen, see edited – slider Apr 13 '16 at 22:05

2 Answers2

0

This type of deep querying on dynamic paths is not possible with Firebase (nor with many other NoSQL databases). What you'll need to do is set up a so-called index, that maps the keys that you want to search for to the values that you want to find.

{
  "Rankings" : {
    "-KFGX5H3rLSnpPvupakm" : {
      "Sports Teams" : {
        "Red sox" : 1,
        "Warriors" : 3,
        "Yankees" : 2
      }
    },
    "-KFGZkwAIl817CLDLmMp" : {
      "Beers" : {
        "Bud light" : 3,
        "Coors" : 2,
        "Pbr" : 4
      }
    }
  },
  "SearchTerms": {
        "Red sox" : {
          "-KFGX5H3rLSnpPvupakm": true
        },
        "Warriors" : {
          "-KFGX5H3rLSnpPvupakm": true
        },
        "Yankees" : {
          "-KFGX5H3rLSnpPvupakm": true
        },
        "Bud light" : {
          "-KFGZkwAIl817CLDLmMp": true
        },
        "Coors" : {
          "-KFGZkwAIl817CLDLmMp": true
        },
        "Pbr" : {
          "-KFGZkwAIl817CLDLmMp": true
        }
  }
}

This process is called denormalizing your data and it's described in this blog post, in the Firebase documentation on structuring data and in this article on NoSQL data modeling. And in probably half a dozen similar answers I've given recently.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • In "SearchTerms", would it be wiser to use an index that maps to a searchable key I can then query for as you have, or store all the same data under "SearchTerms" as stored under "Rankings," without the `autoId`, so I can only spend 1 query? – slider Apr 13 '16 at 23:39
  • Both have their merits. But don't overestimate the overhead of those lookups. See [this answer](http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786) on why Firebase lookup loops may be faster than you expect. – Frank van Puffelen Apr 14 '16 at 04:09
0

I was able to get the values of the child node-id's.

Here is my sample code:

LOCATION_URL.queryOrderedByChild("email").queryEqualToValue(FIRAuth.auth()?.currentUser?.email).observeEventType(.Value, withBlock: { snapShot in

        let enumerator = snapShot.children

        while let rest = enumerator.nextObject() {

            var shot = rest.childSnapshotForPath(rest.key)
            // child node ID
            print(shot.key)

        }
    })

I hope this helps you.. Best regards, Nazar Medeiros

Nazar Medeiros
  • 437
  • 4
  • 10