How I implemented full-text search on Firebase with MeiliSearch for Secrets App.
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)