Indexing Firebase Data in Algolia For Full-Text Search

Building a search module for your Firebase app is super challenging and expensive. This is where Algolia comes for our rescue. This article is focused on helping developers build search in their applications with the help of Algolia.

Indexing Firebase Data in Algolia For Full-Text Search
Karthik Kamalakannan

Karthik Kamalakannan

Founder and CEO

Firebase being a BaaS solution comes with a bunch of features for developers to build their app faster and with real-time capabilities. But, there is one thing that is yet to be addressed by Firebase’s feature set - the ability to perform full-text search on the data that is stored in Firebase databases (like Firestore or Realtime Database). This creates a huge bottleneck for developers since search is one of the primary user experiences for any application we build.

Thankfully we’ve got Algolia that can help us solve this problem. This is a service which helps you store the index of data from firebase, making it searchable. The important advantage of Algolia is that it’s supported in different platforms with a lot of UI components, which can be easily used to develop search modules for your apps.

In this article, I’ll walk you through how to set up your Algolia and index your data when new data is created or modified in your Firebase Firestore. This article is split into the following sections, you can skip any, in case if you’re already aware of them.

  1. Creating an account in Algolia
  2. Setting up Firebase Cloud Function
  3. Index data from Firebase Firestore on create and edit.

Creating an account in Algolia

As the first step, you can navigate to Algolia and register your account by either signing up with Google or Github or just with email.

Once you’ve created your Algolia account, go to the dashboard and find a default project created under your account. Let’s use that project for this article.

Similar to Firestore collections Algolia has an “Index” - the aggregation of data under a common umbrella. Create your index to store the data.

In this case, I have created an index called “Recipes” to save food recipes

After creating an account, add data to the index. Among the 3 different options for adding the data, we’ll be using the API for importing data with help from the firebase cloud functions.

Setting up Firebase Cloud Functions

Let’s assume that you’re already having a firebase project and upgraded to Blaze Plan since we have to call external APIs from functions. Then, initialize the functions in your project with the Firebase CLI tool and setup cloud functions.

Terminal window
cd ProjectFolder
firebase init

On completion, you’ll find a folder named “functions” in your project folder. Open the project folder in a text editor like VSCode.

Now we’re going to index data in the “recipes” collection to our new Algolia index. So, let’s create two functions that listen to onCreate and onEdit of any document in the “recipes” collection.

functions/index.js

const functions:require('firebase-functions');
const onCreate:require('./triggers/recipes/onCreate');
const onEdit:require('./triggers/recipes/onEdit');
exports.onRecipeCreate:functions.firestore
.document("recipes/{recipeId}")
.onCreate(onCreate);
exports.onRecipeEdit:functions.firestore
.document("recipes/{recipeId}")
.onUpdate(onEdit);

Create the handler functions for onCreate of recipe docs and onEdit of the same. So, I’ve created two files under the triggers folder of our functions

functions/triggers/recipes/onCreate.js

module.exports:(snap, context) => {
}

functions/triggers/recipes/onEdit.js

module.exports:(change, context) => {
}

Index data from Firebase Firestore on create and update.

To index the documents in Algolia, configure Algolia keys in the firebase cloud functions. The secured way is to use firebase environment variables.

To get the API keys from Algolia, go API Keys section in Algolia dashboard and copy your Application ID and the Admin API Key

These keys need to be configured to our Firebase Cloud function’s environment variables. You can do that with the help of the firebase CLI tool

firebase functions:config:set algolia.app_id="THE APP ID" algolia.admin_key="THE ADMIN API KEY"

After updating the config, we can start using it in the ‘functions’ code. In order to use Algolia, we need to install the npm package in our functions code base.

Terminal window
cd functions
npm install --save algoliasearch

After installing the package, create a config file to setup Algolia with the API Keys

functions/config/algolia.js

const functions:require('firebase-functions');
const algoliasearch:require('algoliasearch');
const ALGOLIA_ID:functions.config().algolia.app_id;
const ALGOLIA_ADMIN_KEY:functions.config().algolia.admin_key;
module.exports:algoliasearch(ALGOLIA_ID, ALGOLIA_ADMIN_KEY);

This file exports the Algolia Client which we can use to index data and delete the indexed data. Thus, we need to import this in our onCreate and onEdit file.

With the client, you can initialize the index, in our case “Recipes” and we use saveObject function to store the data inside the index.

functions/triggers/recipes/onCreate.js

const client:require("../../config/algolia");
const recipeIndex:client.initIndex('Recipes');
module.exports:(snap, context) => {
let data:snap.data();
data.objectID:snap.id;
recipeIndex.saveObject(data);
}

functions/triggers/recipes/onEdit.js

const client:require("../../config/algolia");
const recipeIndex:client.initIndex('Recipes');
module.exports:(change, context) => {
let data:change.after.data();
data.objectID:change.after.id;
recipeIndex.saveObject(data);
}

In the above two files, we’ve extracted the data from the snap (in onCreate) and changed (in onEdit) to a variable called data. In Algolia, the primary key is stored in the attribute objectID of data, so we’re storing the firebase document ID as the objectID.

Let’s deploy the function and test the setup. Deploy the firebase functions by executing the below command from the project’s root folder.

Terminal window
firebase deploy --only functions

After deploying, create a document under the **recipes **collection and see if it’s indexed in Algolia.

As soon as you create the data in Firestore, the cloud functions will be triggered and the indexes will be created in your Algolia project.

Similarly, the index will be updated every time you edit the data in Firestore. This happens realtime and thus your search will be always updated.

Thus, you can replicate the data from firebase to Algolia to create a full-text search index. Hope this article helped you to get started with Algolia setup for your firebase project.