0

I'm having a bit of trouble with a Firebase query, mainly due to the size of the dataset I am querying.

What I would like to achieve is:

Find all tshirts where brandStartsWith = 'A' and salesRank is between 1 and 100

I've started to pad this out, but I am running into an issue whereby I can't seem to get the data due to having over 300,000 records within t-shirts.

If call it within React when the page loads, after a while I get the following error in console:

Uncaught RangeError: Invalid string length

Here is the code I am using to get me started, but I'm not sure where to go. Looking at the solutions on this question it seems I need to download the data per my query below, and then sort it on the client side. Something I cant seem to do

  firebase.database().ref('tshirts')
    .orderByChild('brandStartsWith')
    .equalTo('A')
    .once('value', function (snapshot) {
       console.log(snapshot.val())
   })
Community
  • 1
  • 1
K20GH
  • 6,032
  • 20
  • 78
  • 118
  • 1
    Possible duplicate of [Query based on multiple where clauses in firebase](http://stackoverflow.com/questions/26700924/query-based-on-multiple-where-clauses-in-firebase) – Jay Feb 08 '17 at 16:57
  • Definitely a duplicate. Strategy 2 of the accepted answer there should work with some adaptation to make rank numbers sortable as strings. – vzsg Feb 08 '17 at 17:01
  • Its not the query at the moment that seems to be causing issues, its the error it throws: Uncaught RangeError: Invalid string length – K20GH Feb 08 '17 at 17:06
  • @K20GH can you set up a jsbin that reproduces the problem? – Frank van Puffelen Feb 08 '17 at 18:15

1 Answers1

2

You're going to need to create a combined key as you can only do one where clause at a time.

{
    "tShirts" : {
        "brandStartsWith" : 'A',
        "salesRank" : 5
        "brandStartsWith_salesRank" = 'A_00005' //pad for as many sales ranks as you have
    }, {
        "brandStartsWith" : 'B',
        "salesRank" : 108
        "brandStartsWith_salesRank" = 'B_00108' //pad for as many sales ranks as you have
    }, {
        "brandStartsWith" : 'C',
        "salesRank" : 52
        "brandStartsWith_salesRank" = 'C_00052' //pad for as many sales ranks as you have
    }
}

This will allow you to do this query:

firebase.database().ref('tshirts')
    .orderByChild('brandStartsWith_salesRank')
    .startAt('A_00001')
    .endAt('A_00100')
    .once('value', function (snapshot) {
        console.log(snapshot.val())
    })

Don't forget to update your rules to .index brandStartsWith_salesRank

Mathew Berg
  • 28,625
  • 11
  • 69
  • 90
  • Is there a fast way to update existing records? I am pulling this information from a 3rd party API which limits 1 call per second. It currently takes almost 72 hours to populate the database... – K20GH Feb 08 '17 at 17:08
  • Just quickly updated my answer. To your question though no, you cannot do that. With firebase you'll have to manage that on your own either when the data is loaded or with some sort of cron job. – Mathew Berg Feb 08 '17 at 17:10
  • Just checking.. is Firebase case-insensitive? Ie is .startAt('A_00001') going to give different results to .startAt('a_00001') – K20GH Feb 08 '17 at 18:00
  • Queries and path matches are case-sensitive. – Frank van Puffelen Feb 08 '17 at 18:10
  • Odd. I've now done this but it only returns null for every request – K20GH Feb 09 '17 at 19:17
  • I'm not sure on the protocol, whether to edit this or create a new question. I would suggest a new one as they may be different. – Mathew Berg Feb 09 '17 at 20:35
  • How can use multiple query. – Raj Aggrawal Nov 11 '17 at 18:51