9

I have data in which I've tried to follow Firebase's advice about flat structure so I'm not pulling more than I need. The net result is I have quotes organised in nodes like this:

quotes -> clientName -> quoteObject

the quoteObjects have a 'dateCreated' value, and I want to be able to pull this data like so (for when I'm pulling one big list of all the quotes for a specific page, I then use object assign to make one big array of objects to display) :

  const quotesRef = firebase.database().ref('quotes');
    quotesRef.orderByChild('dateCreated').on('value', snapshot => {
       // function
    });

Unfortunately the dateCreated value is more than one level deep so the standard query doesn't work. I know you can do a deep path query if you know the parent path, but in my case the clientName parent is always unique. Given this, is it possible to specify a kind of wildcard path? If so how would I go about that? Cheers!

Edit: Showing database example, sorry should have been more specific initially.

quotes
    - ClientEmailOne
        -UniqueQuoteID
            - createdBy: ClientEmailOne
            - dateCreated: 1479255005172
            - email: "clientsEmail@example.com"
    - ClientEmailTwo
        -UniqueQuoteID
            - createdBy: ClientEmailTwo
            - dateCreated: 1479255005172
            - email: "clientsEmail@example.com"
     - ClientEmailThree
         -UniqueQuoteID
            - createdBy: ClientEmailThree
            - dateCreated: 1479255005172
            - email: "clientsEmail@example.com"
        -UniqueQuoteID
            - createdBy: ClientEmailThree
            - dateCreated: 1479255005172
            - email: "clientsEmail@example.com"
        -UniqueQuoteID
            - createdBy: ClientEmailThree
            - dateCreated: 1479255005172
            - email: "clientsEmail@example.com"
Sam Matthews
  • 677
  • 1
  • 12
  • 27

1 Answers1

7

Firebase will consider children of the location you run the query on. The child you specify to order/filter on can contain a path to a property, but it cannot contain any wildcards.

Update:

With your new data structure it seems that you're trying to query across all clients and across all quotes of each of these clients. There are two wildcards in there ("all clients" and "all quotes" under that), which Firebase's querying model doesn't allow.

Your current model allows querying all quotes for a specific client:

ref.child("quotes").child("ClientEmailOne").orderByChild("dateCreated")

If you want to query all quotes across all clients, you'll need to add a data structure that contains all quotes (irrespective of their client):

allquotes
    -UniqueQuoteID
        - createdBy: ClientEmailOne
        - dateCreated: 1479255005172
        - email: "clientsEmail@example.com"
    -UniqueQuoteID
        - createdBy: ClientEmailTwo
        - dateCreated: 1479255005172
        - email: "clientsEmail@example.com"
     -UniqueQuoteID
        - createdBy: ClientEmailThree
        - dateCreated: 1479255005172
        - email: "clientsEmail@example.com"
    -UniqueQuoteID
        - createdBy: ClientEmailThree
        - dateCreated: 1479255005172
        - email: "clientsEmail@example.com"
    -UniqueQuoteID
        - createdBy: ClientEmailThree
        - dateCreated: 1479255005172
        - email: "clientsEmail@example.com"

Then you can query:

ref.child("allquotes").orderByChild("dateCreated")
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks for the fast response Frank! So just to clarify sorry does this mean it should already be ordering by that value as-is (even though it's nested a few levels deep)? Or is it that it's impossible? Because it's coming back unsorted. Thanks – Sam Matthews Nov 16 '16 at 01:02
  • 3
    Firebase can order by nested children *only* when those children are at a fixed path. So you can order `ref.child("quotes").orderByChild("property/under/clientName")`, but not `ref.child("quotes").orderByChild("property/???/clientName")` – Frank van Puffelen Nov 16 '16 at 01:51
  • OK thanks for clarifying. So given that Firebase recommends structuring your data in this way e.g under separate nodes with various id keys, how do they in turn recommend querying in this way? It seems quite a common, simple thing to expect to have to do? Or is it assumed that you just pull the data as is and sort it at your own end? – Sam Matthews Nov 16 '16 at 02:00
  • It will be easier to help if you show a snippet of the actual JSON you're trying to query (as text, no screenshots please). A lot gets lost in translation when you're trying to describe it. – Frank van Puffelen Nov 16 '16 at 03:07
  • OK great have updated sorry about the vagueness thanks a lot! – Sam Matthews Nov 16 '16 at 03:25
  • 1
    That helps a lot (when posting a question, always give a minimal snippet of your actual code and data. Describing it is never as effective as the actual code/data). I updated my answer based on your data. – Frank van Puffelen Nov 16 '16 at 03:37
  • Great thanks a lot for your time and yes you're right sorry about not including the code example earlier. Your answer was what I was trying to avoid but maybe it ultimately could be a better approach. Would it be possible in that structure to quickly pull in the relevant quotes for each user by using the equalTo query? for example ref.orderByChild("createdBy").equalTo(ClientID) ? If so this approach would actually make my data easier to manage as I would be having to sue that whole object assign step – Sam Matthews Nov 16 '16 at 03:44
  • 2
    When using a NoSQL database, you'll find constantly find cases that "require" duplicating data. It's very common, but unnatural for most (SQL oriented) developers. The sooner you get over the natural anxiety that we all have against duplicating data, the sooner you can start reaping the benefits of highly scalable reads. – Frank van Puffelen Nov 16 '16 at 05:02
  • OK understood. Thanks a lot for all your help Frank – Sam Matthews Nov 16 '16 at 06:14