Firestore Full Text Search Package
Tags: firebase, firestore, search
Published: 2021-06-21 23:49:02

If you want full text search capabilities in Firestore, you have limited options... until now.  Firebase recommends Algolia. Yes, Google recommends Algolia instead of a Google product to have search capabilities in a Google product. I digress.  Basically, you have these options:
___
**UPDATE 10/23/22** - I have since retired this package. I recommend using my [j-firebase](https://code.build/p/DFLH9m8hucp8k4UeDL3ZDm/firestore-fuzzy-full-text-search) package.
___
- [Algolia](https://www.algolia.com/) - semi supports relational data
- [Elastic Search](https://www.elastic.co/) - there are many forks as well, but ultimately you don't have all options out of the box
- [MeiliSearch](https://www.meilisearch.com/) - host it yourself... see [here](https://fireship.io/lessons/meilisearch-firebase-google-cloud/)
- [Typesense](https://typesense.org/) - self-hosting as well

You can also use pretty much any search engine that you can connect your data to using firebase trigger functions. However, I like to keep my data in Firebase.

I have a [hate/love relationship](https://code.build/p/VCg7fQ3GAwbrqWmqgaXMec/dear-firebase-team) with Firestore like everyone else, but I wrote a package that allows you to full-text search data in Firestore, by creating indexes in Firestore. While I had three different ideas to do this, see [here](https://code.build/p/5XSkVJhq5BpEUuKPfzkJXU/which-full-text-search-index-do-i-use) for my article, there is only one package I think works for most people...

## Relevant Search

1.) `npm i adv-firestore-functions`

2.) Add the function to a **onWrite** trigger function like so:

```typescript
import { soundex, relevantIndex } from 'adv-firestore-functions';

...
functions.firestore
    .document('posts/{docId}')
    .onWrite(async (change: any, context: any) => {

...

   await relevantIndex(change, context, {
      fields: ['content', 'summary'],
      filterFunc: soundex
   });

}
```
The soundex function allows you to do a fuzzy search. While not perfect, it should take care of most of your needs. I made it optional in case you don't want to use it, or you want to use your own changing algorithm.

3.) Add / Edit / Delete a new Post (or whatever collection) - Everything is changed and updated automatically on the backend.

4.) Make sure to add rules for your collection as well as **_search** and **_events** collection. They both need to be writable by Firestore, while **_search** needs to be readable on the client side by anyone.

5.) Use my pre-written Firestore Callable Function to read the indexed data on the front end:

```typescript
import { relevantSearch } from 'adv-firestore-functions';
...

exports.searchPosts = functions.https.onCall((q, context) => {

  return await relevantSearch({
    query: q.query,
    col: 'posts',
  });
...
}
```

or write your own:
- [Observable Version](https://gist.github.com/jdgamble555/e6d65b67f2da3ad6b6f676c3a1860800) - This is my Trigram Search, but same premise
- [Promise Version](https://github.com/jdgamble555/adv-firestore-functions/blob/master/src/shared/search.ts#L150) - Backend Version could easily be implemented on Front End

If you have other needs, check out my other searches:

- [Which Full-Text Search Index Do I Use?](https://code.build/p/5XSkVJhq5BpEUuKPfzkJXU/which-full-text-search-index-do-i-use) - my Fireblog.io 
- [adv-firestore-functions](https://github.com/jdgamble555/adv-firestore-functions) - GitHub project

While I may or may not be done with Firestore, see [Dear Firebase Team...](https://code.build/p/VCg7fQ3GAwbrqWmqgaXMec/dear-firebase-team), I wrote this package a while ago and needed to share it.

Post on GitHub if you have issues or ideas.

Thanks,

J