Skip to main content
RapidDev - Software Development Agency
firebase-tutorial

How to Use Firebase with Algolia for Full-Text Search

To add full-text search to Firebase, sync your Firestore data to Algolia using a Cloud Function that triggers on document writes. Each time a document is created, updated, or deleted, the function mirrors the change in an Algolia index. On the client side, use Algolia's InstantSearch library for real-time search UI with facets, highlighting, and typo tolerance that Firestore cannot provide natively.

What you'll learn

  • How to create a Cloud Function that syncs Firestore documents to Algolia
  • How to configure Algolia index settings for optimal search results
  • How to build an InstantSearch UI that queries Algolia from the browser
  • How to handle document updates and deletions to keep the index consistent
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate7 min read20-25 minFirebase JS SDK v9+, Cloud Functions v2, Algolia algoliasearch v4+, Node.js 18+March 2026RapidDev Engineering Team
TL;DR

To add full-text search to Firebase, sync your Firestore data to Algolia using a Cloud Function that triggers on document writes. Each time a document is created, updated, or deleted, the function mirrors the change in an Algolia index. On the client side, use Algolia's InstantSearch library for real-time search UI with facets, highlighting, and typo tolerance that Firestore cannot provide natively.

Adding Full-Text Search to Firebase with Algolia

Firestore does not support full-text search natively. The standard solution is to sync Firestore data to a dedicated search service like Algolia, which provides typo tolerance, faceted filtering, and sub-50ms query times. This tutorial shows you how to create Firestore triggers that keep an Algolia index in sync and how to build a search interface using Algolia's InstantSearch React library.

Prerequisites

  • A Firebase project on the Blaze plan (required for Cloud Functions and outbound network calls)
  • An Algolia account with an application ID and Admin API Key (free tier available)
  • Cloud Functions initialized in your project (firebase init functions)
  • Node.js 18+ installed

Step-by-step guide

1

Install Algolia SDK in your functions directory

Navigate to your functions directory and install the Algolia search client. This package runs server-side inside Cloud Functions. You will use the Admin API key to write to the Algolia index, so it must never be exposed to the client.

typescript
1cd functions
2npm install algoliasearch

Expected result: algoliasearch is added to functions/package.json dependencies.

2

Store Algolia credentials as secrets

Use Firebase's defineSecret to store your Algolia Application ID and Admin API Key in Cloud Secret Manager. This avoids hardcoding sensitive values and makes them available to your Cloud Functions at runtime.

typescript
1// functions/src/index.ts
2import { defineSecret } from 'firebase-functions/params'
3
4const ALGOLIA_APP_ID = defineSecret('ALGOLIA_APP_ID')
5const ALGOLIA_ADMIN_KEY = defineSecret('ALGOLIA_ADMIN_KEY')
6
7// Set the secrets:
8// firebase functions:secrets:set ALGOLIA_APP_ID
9// firebase functions:secrets:set ALGOLIA_ADMIN_KEY

Expected result: Secrets are stored in Cloud Secret Manager and accessible in your function code.

3

Create a Firestore trigger to sync data to Algolia

Write a Cloud Function v2 that fires on document writes in your target collection. On create and update events, the function saves the document data plus its Firestore ID as the Algolia objectID. On delete, it removes the record from the index. The function must declare the secrets it needs in its options.

typescript
1// functions/src/index.ts
2import { onDocumentWritten } from 'firebase-functions/v2/firestore'
3import algoliasearch from 'algoliasearch'
4
5const ALGOLIA_APP_ID = defineSecret('ALGOLIA_APP_ID')
6const ALGOLIA_ADMIN_KEY = defineSecret('ALGOLIA_ADMIN_KEY')
7const ALGOLIA_INDEX_NAME = 'products'
8
9export const syncToAlgolia = onDocumentWritten(
10 {
11 document: 'products/{productId}',
12 secrets: [ALGOLIA_APP_ID, ALGOLIA_ADMIN_KEY]
13 },
14 async (event) => {
15 const client = algoliasearch(
16 ALGOLIA_APP_ID.value(),
17 ALGOLIA_ADMIN_KEY.value()
18 )
19 const index = client.initIndex(ALGOLIA_INDEX_NAME)
20 const { productId } = event.params
21
22 // Document was deleted
23 if (!event.data?.after.exists) {
24 await index.deleteObject(productId)
25 return
26 }
27
28 // Document was created or updated
29 const data = event.data.after.data()
30 await index.saveObject({
31 objectID: productId,
32 ...data
33 })
34 }
35)

Expected result: Every Firestore write to the products collection is mirrored to the Algolia index.

4

Configure Algolia index settings

Set searchable attributes and ranking criteria in the Algolia dashboard or programmatically. This tells Algolia which fields to search and how to rank results. Configure this once; the settings persist across all future indexing operations.

typescript
1// One-time setup script (run locally)
2import algoliasearch from 'algoliasearch'
3
4const client = algoliasearch('YOUR_APP_ID', 'YOUR_ADMIN_KEY')
5const index = client.initIndex('products')
6
7await index.setSettings({
8 searchableAttributes: ['name', 'description', 'category'],
9 attributesForFaceting: ['category', 'price'],
10 customRanking: ['desc(createdAt)']
11})

Expected result: Algolia searches the name, description, and category fields and supports faceted filtering on category and price.

5

Build the search UI with InstantSearch

Install Algolia's InstantSearch library for your frontend framework and create a search component. Use the Search-Only API Key (not the Admin key) for client-side queries. InstantSearch provides pre-built widgets for search boxes, hit lists, facet filters, and pagination.

typescript
1npm install algoliasearch react-instantsearch
2
3// src/components/Search.tsx
4import algoliasearch from 'algoliasearch/lite'
5import { InstantSearch, SearchBox, Hits, Highlight } from 'react-instantsearch'
6
7const searchClient = algoliasearch(
8 import.meta.env.VITE_ALGOLIA_APP_ID,
9 import.meta.env.VITE_ALGOLIA_SEARCH_KEY
10)
11
12function Hit({ hit }: { hit: any }) {
13 return (
14 <div>
15 <h3><Highlight attribute="name" hit={hit} /></h3>
16 <p>{hit.description}</p>
17 </div>
18 )
19}
20
21export function Search() {
22 return (
23 <InstantSearch searchClient={searchClient} indexName="products">
24 <SearchBox placeholder="Search products..." />
25 <Hits hitComponent={Hit} />
26 </InstantSearch>
27 )
28}

Expected result: A search box appears that queries Algolia in real-time and displays matching products with highlighted terms.

6

Deploy and test the sync function

Deploy your Cloud Function and create a test document in Firestore. Check the Algolia dashboard to verify the document appears in the index. Then update and delete the document to confirm the sync function handles all write types correctly.

typescript
1firebase deploy --only functions:syncToAlgolia

Expected result: The function deploys successfully. Creating a document in the products collection triggers indexing in Algolia within seconds.

Complete working example

functions/src/index.ts
1// functions/src/index.ts
2import { onDocumentWritten } from 'firebase-functions/v2/firestore'
3import { defineSecret } from 'firebase-functions/params'
4import algoliasearch from 'algoliasearch'
5
6const ALGOLIA_APP_ID = defineSecret('ALGOLIA_APP_ID')
7const ALGOLIA_ADMIN_KEY = defineSecret('ALGOLIA_ADMIN_KEY')
8const ALGOLIA_INDEX_NAME = 'products'
9
10export const syncToAlgolia = onDocumentWritten(
11 {
12 document: 'products/{productId}',
13 secrets: [ALGOLIA_APP_ID, ALGOLIA_ADMIN_KEY]
14 },
15 async (event) => {
16 const client = algoliasearch(
17 ALGOLIA_APP_ID.value(),
18 ALGOLIA_ADMIN_KEY.value()
19 )
20 const index = client.initIndex(ALGOLIA_INDEX_NAME)
21 const { productId } = event.params
22
23 // Handle deletion
24 if (!event.data?.after.exists) {
25 await index.deleteObject(productId)
26 console.log(`Deleted ${productId} from Algolia`)
27 return
28 }
29
30 // Handle create or update
31 const data = event.data.after.data()
32 await index.saveObject({
33 objectID: productId,
34 name: data?.name,
35 description: data?.description,
36 category: data?.category,
37 price: data?.price,
38 createdAt: data?.createdAt?.toMillis() ?? Date.now()
39 })
40 console.log(`Synced ${productId} to Algolia`)
41 }
42)

Common mistakes when using Firebase with Algolia for Full-Text Search

Why it's a problem: Using the Algolia Admin API Key on the client side, which gives anyone full write and delete access to your index

How to avoid: Use the Search-Only API Key for client-side queries. The Admin key must only be used in Cloud Functions or other server-side code.

Why it's a problem: Forgetting to set objectID when saving to Algolia, causing Algolia to generate random IDs that cannot be matched to Firestore documents

How to avoid: Always set objectID to the Firestore document ID. This allows update and delete operations to target the correct Algolia record.

Why it's a problem: Not handling the delete case in the onDocumentWritten trigger, leaving orphaned records in the Algolia index

How to avoid: Check if event.data.after.exists is false. If the document was deleted, call index.deleteObject with the document ID to remove it from Algolia.

Why it's a problem: Syncing all document fields to Algolia including sensitive data like user emails or internal IDs

How to avoid: Explicitly select which fields to index by destructuring only the fields you want. Never sync entire documents blindly with the spread operator in production.

Best practices

  • Store Algolia Admin API Key in Cloud Secret Manager using defineSecret, never in .env files or source code
  • Use the algoliasearch/lite bundle on the client for a smaller bundle size
  • Set searchableAttributes in Algolia to control which fields are searched and in what priority order
  • Include the Firestore document ID as the Algolia objectID to maintain a 1:1 mapping for updates and deletes
  • For initial backfill of existing data, write a one-time script that reads all Firestore documents and batch-indexes them to Algolia
  • If your project involves complex search requirements across multiple collections, RapidDev can help architect the sync pipeline and search infrastructure
  • Monitor Algolia usage in the dashboard to stay within your plan's record and operation limits

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I have a Firestore collection called 'articles' with fields title, body, and tags. Show me how to write a Cloud Function v2 that syncs this collection to Algolia on every create, update, and delete. Also show the client-side search component using react-instantsearch.

Firebase Prompt

Create a Firebase Cloud Function that syncs my 'products' Firestore collection to an Algolia search index. Use onDocumentWritten triggers with v2 syntax, store the Algolia credentials with defineSecret, and handle creates, updates, and deletes. Include the Algolia index configuration for searchable attributes.

Frequently asked questions

Is there a Firebase Extension for Algolia?

Yes. The 'Search with Algolia' extension automates the sync between Firestore and Algolia without writing custom Cloud Functions. Install it from the Firebase Extensions Hub and configure the collection path, fields to sync, and Algolia credentials.

How much does Algolia cost for Firebase projects?

Algolia offers a free tier with 10,000 search requests per month and 10,000 records. The paid plans start at $1 per 1,000 search requests. For most Firebase projects in early stages, the free tier is sufficient.

Can I use Typesense instead of Algolia?

Yes. Typesense is an open-source alternative you can self-host. The sync pattern is identical: create a Cloud Function trigger that writes to the Typesense API on Firestore document changes. Typesense also has a Firebase Extension.

How do I backfill existing Firestore data to Algolia?

Write a one-time Node.js script that reads all documents from your Firestore collection using the Admin SDK and batch-indexes them to Algolia using index.saveObjects(). After the backfill, the Cloud Function trigger handles ongoing syncs.

Will the sync function slow down my Firestore writes?

No. Firestore triggers are asynchronous. The write to Firestore completes immediately and the Cloud Function runs in the background. Users do not experience any latency from the Algolia sync.

How do I handle partial updates without overwriting the entire Algolia record?

Use index.partialUpdateObject() instead of saveObject() if you only want to update specific fields. However, for most use cases, saving the full object on each update is simpler and ensures consistency.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.