How I implemented full-text search on Firebase with MeiliSearch for Secrets App.

Steven Albert Ogwal
4 min readSep 6, 2021

--

What is Secrets?

Secrets is a safe social space for people who want to share their thoughts and feelings anonymously.

Demo

The challenge

Full-text search has always been a challenge with firebase because Cloud Firestore doesn’t support native indexing or search for text fields in documents. Additionally, downloading an entire collection to search for fields client-side isn’t practical. Therefore, to enable full text search of your Cloud Firestore data, we have to use a dedicated third-party search service.

  • Elastic (High cost)
  • Algolia (High cost)
  • Meilisearch (Affordable) — Self Hosted

What is MeiliSearch

MeiliSearch is a RESTful search API. It aims to be a ready-to-go solution for everyone who wants a fast and relevant search experience for their end-users.

All of MeiliSearch’s features are provided right out of the box, and can be easily configured.

The solution using MeiliSearch & Cloud Functions in Flutter

Run MeiliSearch

There are many easy ways to download and run a MeiliSearch instance.

For example, if you use Docker:

docker pull getmeili/meilisearch:latest # Fetch the latest version of MeiliSearch image from Docker Hubdocker run -it --rm -p 7700:7700 getmeili/meilisearch:latest ./meilisearch --master-key=masterKey

NB: you can also download MeiliSearch from Homebrew or APT.

Adding records with Cloud Functions

With npm:

npm install meilisearch

Cloud functionsindex.js:

const functions = require("firebase-functions");
const { MeiliSearch } = require('meilisearch');
const admin = require('firebase-admin');
admin.initializeApp();const client = new MeiliSearch({
host: '<http://127.0.0.1:7700>',
apiKey: 'masterKey',
});
// Add the search index every time a secret post is written.
exports.onCreateSecret = functions.firestore.document('secrets/{id}')
.onCreate((snap, context) => {
// Create a document
const documents = [
{
id: snapshot.id,
secret: snapshot.data().secret,
authorName: snapshot.data().authorName,
authorUid: snapshot.data().authorUid,
timestamp: new Date(timestamp.seconds*1000).toLocaleDateString()
}
];

// Write to the meilisearch index
let response = await client.index('secrets').addDocuments(documents);
console.log(response); // => { "updateId": 0 }
});

Installation in Flutter

You can install the meilisearch package by adding a few lines into pubspec.yaml file.

Searching for records

// a function to search with meilisearch
Future<void> searchSecrets(String _query) async {
try {
var client = MeiliSearchClient('<http://127.0.0.1:7700>', 'masterKey');
var index = client.index('secrets');
var results = await index.search(_query);
if (results.hits!.length == 0) {
print('No results found');
}else{
print(results.hits);
}
} catch (e) {
print('Error: $e');
}
}

Result

Demo

Deploying

Since meilisearch is self-hosted, This gives you the freedom of control. Meilisearch can be deployed anywhere of your choice (docker-containers).

Here is a guide on how to deploy.

For my project, i used Qovery which offered a free plan at $0.

Qovery is a platform that combines the power of Kubernetes, the reliability of AWS, and the simplicity of Heroku to deploy your applications in the Cloud.

Source Code

Who am I?

I’m Steven Albert Ogwal a self-motivated Software Developer skilled at technical leadership, communication and presentations. Experienced in full project life cycle from design to implementation to integration. Able to deliver in a timely fashion with minimum supervision. Expert in diverse programming languages, including C,C++,Java,Dart,PHP,NodeJS and Python.

Contact Me: (ogsteval@gmail.com)

--

--

Steven Albert Ogwal

I'm a self-motivated & flexible individual with strong analytical skills and experience in software development, user support, and operations.