2

I have a firebase database structure similar to this

enter image description here

Is it possible to query by the email address say "a@a.com" and retrieve both the keys "1248769d7j8" as well its parent "deaf7834jd8d7j-78" ?

The solution I have is to make the database structure flatter. But am wondering if it is possible to get by without denormalization

Update: In my case both 124... and dea... are unknown, unique IDs

sera
  • 111
  • 2
  • 10
  • 1
    No, it's not possible. You can specify deep paths when ordering by child (e.g. `some/deep/property`) and when defining indices, but the components of said paths need to be known names (so to speak) and `1248769d7j8` appears to be an ID which would not be known when you'd be defining the security rules (for indices), etc. – cartant Feb 11 '17 at 05:48
  • Thanks I thought so. Will create a different branch of the database – sera Feb 11 '17 at 07:40
  • @cartant Please see the answer as this is very easy to do. – Jay Feb 11 '17 at 16:54
  • @Jay I should have said something more like: *No, it's not possible for that data to be indexed for the query you want to make*. I note that your answer does not use the OP's data. If it did, you'd have a `queryOrdered(byChild: "1248769d7j8/email")` in it - which clearly cannot be indexed. Any answer recommending that approach should include a caveat. – cartant Feb 11 '17 at 18:57
  • @cartant Not sure what you are referring to as indexing has nothing to do with the answer. Also, more importantly the answer works equally well with the OP data (just tested it) - all key names are strings and treated the same way in Firebase - whether it be '1247869d7j8' or 'details'. Perhaps I misunderstand the comment. – Jay Feb 11 '17 at 19:34
  • @cartant I see. You assume the 124... is an unknown. I assume it would be a node name repeated in each child. So in your case, you are correct. In my case my solution works. Hopefully the OP can make that a set node name so it will work. – Jay Feb 11 '17 at 19:56
  • @Jay Yep. I assumed it was an ID of which there would be many - which I still think is a reasonable assumption. And, yeah, that initial comment was incorrect, as it clearly is possible, just not something that should be done if it cannot be indexed. – cartant Feb 11 '17 at 20:01
  • Thanks @Jay. Just to clarify, in my case both 124... and dea... are unknown, unique IDs – sera Feb 12 '17 at 10:58
  • Thanks for the additional info. I updated my answer to go along with @cartant comment that No, it is not possible. For this case, denormalizing is the way to go. – Jay Feb 12 '17 at 15:53

1 Answers1

3

Edit: The answer was initially Yes, however, with updated information from the OP, both the parent node 'deaf...' and child node '1248...' are both unknowns so there would be no way to craft a deep query.

If the child node '1248' was consistent as the key for each child node of the deaf... node then the answer is yes.

Yes, you can certainly get the parent node as well as the parent's parent. This is Swift since the platform was not specified but the concept is the same across the board.

Given a structure

root
  posts
    post_1
      details
         posted_by: "Leroy"
    post_2
      details
         posted_by: "Bill"

Let's do a query for the Leroy node via a deep query:

let postsRef = ref.child("posts")

let queryRef = dataRef.queryOrdered(byChild: "details/posted_by")
                      .queryEqual(toValue: "Leroy")
queryRef.observeSingleEvent(of: .value, with: { (snapshot) in
   let a = snapshot.key //the posts node
   print(a)

   for child in snapshot.children {
       let childSnap = child as! FIRDataSnapshot        
       print(childSnap.key) //the direct parent node
   }
})

and the result will print

posts
post_1

Another option is to include the parent node in the lower level node like this

root
  deaf91298823
    1248
     email: "asad@asdd.com"
     name: "Adam"
     parent_node: "1248"
     parent_parent: "deaf91298823"
Jay
  • 34,438
  • 18
  • 52
  • 81
  • For anyone in a similar quandary, this is a great answer. However, in my case, I can't do `let postsRef = ref.child("posts")` since posts is an unknown, unique ID. Updated my question to clarify. – sera Feb 12 '17 at 11:01