vir us
vir us

Reputation: 10725

Firebase database startAt() string parameter length limit?

Was about to post this to their github repo, but seems like they prefer general questions to be asked here instead.

So is there any string length limit for parameter when using startAt() to get data from firebase database?

I've juts run into an issue where it seems like it's limited to only 41 symbol and I can't seem to find any docs to confirm that.

If it is indeed the limit, then is there any way to change it? (I need to be able to filter by values with up to 60 symbols)

I mean, I still can pass longer parameters, but the database returns results that are only filtered out by the first 41 characters ignoring the rest of the value.

I'm using js sdk in case it matters here.

The dataset (each value is about 100 characters long and the first 41 characters are identical in each of them but defferes at tails )

{
  "obj1": {"param": "abcdefghijklmnopqrstuvwxyz0123456789ABCDEF_0123456789ABCDEFabcdefghijklmnopqrstuvwxyz0123456789ABCDEF"},
  "obj2": {"param": "abcdefghijklmnopqrstuvwxyz0123456789ABCDEF_123456789ABCDEFabcdefghijklmnopqrstuvwxyz0123456789ABCDEF"},
  "obj3": {"param": "abcdefghijklmnopqrstuvwxyz0123456789ABCDEF_23456789ABCDEFabcdefghijklmnopqrstuvwxyz0123456789ABCDEF"},
  "obj4": {"param": "abcdefghijklmnopqrstuvwxyz0123456789ABCDEF_3456789ABCDEFabcdefghijklmnopqrstuvwxyz0123456789ABCDEF"},
  "obj5": {"param": "abcdefghijklmnopqrstuvwxyz0123456789ABCDEF_456789ABCDEFabcdefghijklmnopqrstuvwxyz0123456789ABCDEF"}
}

Now I need to retrieve the "obj1" by value of the key "param" and I know only the first 60 characters of it (so I can't use equalTo() )

var ref = firebase.database().ref("/some/data");

ref.orderByChild("param")
   .startAt("abcdefghijklmnopqrstuvwxyz0123456789ABCDEF_0123456789ABCDEFabc") <- this guy is 60 characters long
   .once("value")
   .then(function(snapshot) {
     snapshot.forEach(function(child) {
       console.log(child.key);
     });
   })

I'd expect only one result here, but instead the code above returns all the records from the set.

Upvotes: 0

Views: 634

Answers (2)

Frank van Puffelen
Frank van Puffelen

Reputation: 599491

It seems like you're confused about the startAt operation, and are trying to use it to filter strings that start with a certain substring. That's not how startAt works however.

When you order the children by the value of param, Firebase orders all children by the value of that property. When you then start at abcdefghijklmnopqrstuvwxyz0123456789ABCDEF_0123456789ABCDEFabc it starts returning nodes from that point onwards. And in that order abcdefghijklmnopqrstuvwxyz0123456789ABCDEF_123456789ABCDEFabcdefghijklmnopqrstuvwxyz0123456789ABCDEF comes after abcdefghijklmnopqrstuvwxyz0123456789ABCDEF_0123456789ABCDEFabc.

If you want the first child starting at a certain value, consider using .startAt(searchTerm).limitToFirst(1).

If you want to get the children starting with a certain value, use a closed range startAt(searchTerm).endAt(searchTerm+"\uf8ff"). Here \uf8ff is the last unicode character.

Upvotes: 4

Frank van Puffelen
Frank van Puffelen

Reputation: 599491

I just tried reproducing this problem in a JavaScript project, and in a Swift project, but was unable to.

My data set:

{
  "key1" : "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
  "key2" : "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFZHIJKLMNOPQRSTUVWXYZ0123456789",
  "key3" : "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFHHIJKLMNOPQRSTUVWXYZ0123456789",
  "key4" : "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFIHIJKLMNOPQRSTUVWXYZ0123456789",
  "key5" : "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFJHIJKLMNOPQRSTUVWXYZ0123456789"
}

My JavaScript code:

var ref = firebase.database().ref("/51151783");

ref.orderByValue()
   .startAt("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFI")
   .once("value")
   .then(function(snapshot) {
     snapshot.forEach(function(child) {
       console.log(child.key);
     });
   })

My Swift code:

func searchForLongValue51151783() {
    let ref = Database.database().reference(withPath: "51151783")
    ref.queryOrderedByValue().queryStarting(atValue: "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFI").observeSingleEvent(of: .value, with: { (snapshot) in
            for child in snapshot.children {
                print((child as! DataSnapshot).key)
            }
    })
}

This outputs:

key4

key5

key2

And the jsbin: http://jsbin.com/lupebuwihu/edit?js,console.

Upvotes: 1

Related Questions