Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autocomplete with Firebase

How does one use Firebase to do basic auto-completion/text preview?

For example, imagine a blog backed by Firebase where the blogger can tag posts with tags. As the blogger is tagging a new post, it would be helpful if they could see all currently-existing tags that matched the first few keystrokes they've entered. So if "blog," "black," "blazing saddles," and "bulldogs" were tags, if the user types "bl" they get the first three but not "bulldogs."

My initial thought was that we could set the tag with the priority of the tag, and use startAt, such that our query would look something like:

fb.child('tags').startAt('bl').limitToFirst(5).once('value', function(snap) {
  console.log(snap.val()) 
});

But this would also return "bulldog" as one of the results (not the end of the world, but not the best either). Using startAt('bl').endAt('bl') returns no results. Is there another way to accomplish this?

(I know that one option is that this is something we could use a search server, like ElasticSearch, for -- see https://www.firebase.com/blog/2014-01-02-queries-part-two.html -- but I'd love to keep as much in Firebase as possible.)

Edit

As Kato suggested, here's a concrete example. We have 20,000 users, with their names stored as such:

/users/$userId/name

Oftentimes, users will be looking up another user by name. As a user is looking up their buddy, we'd like a drop-down to populate a list of users whose names start with the letters that the searcher has inputted. So if I typed in "Ja" I would expect to see "Jake Heller," "jake gyllenhaal," "Jack Donaghy," etc. in the drop-down.

like image 957
Jake Avatar asked May 07 '14 00:05

Jake


People also ask

What is firebase app?

Firebase provides detailed documentation and cross-platform SDKs to help you build and ship apps on Android, iOS, the web, C++, and Unity.

How do I find firebase?

Ways to Filter and Search data in Firebase Realtime databaseThrough the use of id , which is typically used to look for a specific value that has its id . Through the use of a child path from which any changes to data in the database are listed. Through the use of a variable that can be given as a parameter.


2 Answers

I know this is an old topic, but it's still relevant. Based on Neil's answer above, you more easily search doing the following:

fb.child('tags').startAt(queryString).endAt(queryString + '\uf8ff').limit(5)

See Firebase Retrieving Data.

The \uf8ff character used in the query above is a very high code point in the Unicode range. Because it is after most regular characters in Unicode, the query matches all values that start with queryString.

like image 199
Matt McCallum Avatar answered Sep 21 '22 18:09

Matt McCallum


As inspired by Kato's comments -- one way to approach this problem is to set the priority to the field you want to search on for your autocomplete and use startAt(), limit(), and client-side filtering to return only the results that you want. You'll want to make sure that the priority and the search term is lower-cased, since Firebase is case-sensitive.

This is a crude example to demonstrate this using the Users example I laid out in the question:

For a search for "ja", assuming all users have their priority set to the lowercased version of the user's name:

fb.child('users').
  startAt('ja'). // The user-inputted search
  limitToFirst(20).
  once('value', function(snap) {
    for(key in snap.val()){
      if(snap.val()[key].indexOf('ja') === 0) {
        console.log(snap.val()[key];
      }
    }
});

This should only return the names that actually begin with "ja" (even if Firebase actually returns names alphabetically after "ja").

I choose to use limitToFirst(20) to keep the response size small and because, realistically, you'll never need more than 20 for the autocomplete drop-down. There are probably better ways to do the filtering, but this should at least demonstrate the concept.

Hope this helps someone! And it's quite possible the Firebase guys have a better answer.

(Note that this is very limited -- if someone searches for the last name, it won't return what they're looking for. Hence the "best" answer is probably to use a search backend with something like Kato's Flashlight.)

like image 24
Jake Avatar answered Sep 23 '22 18:09

Jake