3

I would like to create a search feature for my apps by using firebase real time database, which similar to facebook search.

I did some research and acknowledge that firebase real time is not able to search with "text contain". But i believe there must be some method to achieve it, like combine startAt or endAt.

I need some advise the best practice to do it.

The DB structure will look like:

Restaurant
-->RandomID
---->name: 'Good Restaurant'
---->address:
---->desc:
-->RandomID
---->name: 'Dixon Lee Restaurant'
---->address:
---->desc:
-->RandomID
---->name: 'MCD'
---->address:
---->desc:

Edited I not sure how the startAt and endAt work. Is it supposes to return 3 and above if i use startAt(3)? What if i use startAt with string? Like below problem i ecnounter:

firebase.database().ref('/restaurants').orderByChild('name').startAt('Good').on('value',snap=>{
      console.log(snap.val())
    })

The above query will return: enter image description here

I am thinking to achieve "text contains" with startAt/endAt, which will find specific value of field that begin/end with a keyword. Not sure is this the usage for startAt/endAt.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Jerry
  • 1,455
  • 1
  • 18
  • 39
  • 2
    Since you've already found answers about it, what specific do you think is possible and how it fits with those other answers? Otherwise I'm not sure what to answer or how it's different from the existing answers (which are quite plentiful). – Frank van Puffelen Apr 10 '18 at 23:17
  • @FrankvanPuffelen thanks for always responding to the firebase question. I have problem with the usage of startAt and endAt, the documentation doesn't clear enough to guide a rookie like me.. I have updated the post with the problem i encountered. – Jerry Apr 11 '18 at 02:04

2 Answers2

6

You seem to be confusing startAt with a function that would accepts strings that start with a certain value. That's simply not how Firebase filtering work.

When you do ref('/restaurants').orderByChild('name').startAt('Good'), it does three things:

  1. Orders all child nodes of restaurants on their name value.
  2. Find the first one starting with Good (or anything lexicographically after Good)
  3. Returns every child from there on

So you're getting the child nodes with name Good Restaurant and MCD.

You can use startAt and endAt to return a range of child nodes, i.e. all the ones starting with Good. To do this you create a range starting at Good and ending at Good\uF8FF:

ref('/restaurants').orderByChild('name').startAt('Good').endAt('Good\uF7FF')

Since \uF8FF is the last known Unicode character, this query returns items starting with e.g. Good, Goodie, Goodness, but not Gooey (since Gooe is after Good\uF7FF).

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks for explaining, i not sure am i understand and i also not sure how to ask further... orderByChild('name') will make all my restaurant list according “name" property from A to Z, and startAt('Good') will return all the restaurant (as an object) that after "G"? If i have "Fun", "Happy", "Better", "Crazy" and "Inspire" Restaurant, it will return Fun, Happy, Inspire Restaurant to me? Furthermore, i don't understand how endAt work and what does \uF8FF mean. I googled it, they say is "last" but i not sure how it work with endAt – Jerry Apr 11 '18 at 13:17
  • If you order "Fun", "Happy", "Better", "Crazy" and "Inspire" alphabetically, you get "Better", "Crazy", "Fun", "Happy", "Inspire". If you then start at "Good" (so drop everything before "Good") you will get "Happy", and "Inspire". If you start at "Good" and end at "Hollow", you will only get "Happy". – Frank van Puffelen Apr 11 '18 at 14:57
  • Lets say i order "Fun Restaurant", "Happy Cafe", "Better Restaurant", "Crazy cafe", "Good Restaurant" and "Inspire Coffee Shop" alphabetically, i will get "Better Restaurant", "Crazy cafe", "Fun Restaurant", "Good Restaurant" ,"Happy Cafe" and "Inspire Coffee Shop" right? How do i get "Better Restaurant", "Fun Restaurant" and "Good Restaurant" by querying "Restaurant"? or get "Inspire Coffee Shop" by querying Coffee or Shop? Is that even possible? or is firestore able to achieve it? Thanks again! – Jerry Apr 11 '18 at 15:42
  • That's a query for a substring, which isn't possible with Firebase database queries. See https://stackoverflow.com/questions/28589092/firebase-query-find-item-with-child-that-contains-string – Frank van Puffelen Apr 11 '18 at 17:27
3

For full text search with Firebase you you are better off using Algolia, as recomended in the full-text search page in the official Firebase documentation. Here is an easy to follow tutorial for Realtime Database:

Firebase Algolia Tutorial

It is free to use if you have less then 10k records.

Andrii Rudavko
  • 370
  • 1
  • 7