Flutter SearchDelegate + Algolia

Mohammad Norhamizan
Flutter Community
Published in
3 min readSep 28, 2019

Currently, Firestore does not offer full-text search feature. The best you can get is a search that matches against the first few characters of your query with the value in your documents. Like so,

Firestore.instance
.collection('collection-name')
.orderBy('name')
.startAt([query])
.endAt([query + '\uf8ff']).snapshots()
// from https://stackoverflow.com/a/56747021/4767950

One way to implement a full-text search function is by using a service like Algolia or ElasticSearch. This will power your Flutter app a full-text functionality instead of using a basic startAt and endAt query from Firestore.

For this article, I will mainly write about setting up Flutter’s SearchDelegate so I will not go into the details of setting up and indexing your Firestore documents into Algolia. Check out Rafael Farias post on how to set up this part. Following through until Step 5 of Part 1 is sufficient for this article.

Search Page

The showSearch function shows a full screen search page and returns the search result selected by the user when the page is closed.

Docs: https://api.flutter.dev/flutter/material/showSearch.html

To use the showSearch page, we only have to fire the function during any action. This function is available through the material library. For the sake of simplicity, I will show an example that triggers showSearch.

An example of a widget that triggers showSearch when onTap is fired

The showSearch function takes the current context and the SearchDelegate that we will write in the second part.

Creating a SearchDelegate

First, create a class that extends the SearchDelegate class. This is also available through the material library. Then, you will have to implement the superclass method buildActions, buildLeading, buildResults and buildSuggestions.

David Anderson did a great post on how to set up your own SearchDelegate. Be sure to check out his post on how to implement the buildActions and buildLeading of the superclass functions. This article will only focus on the buildResults function to get the search result from Algolia.

FutureBuilder to the rescue

To implement Algolia, we’ll be using the unofficial Algolia dart package. To get the results from Algolia we will be using FutureBuilder class.Use FutureBuilder and pass Future<AlgoliaQuerySnapshot> using getObjects method. Then you can use the builder to build your UI. In the example below, I used ListView and ListTile to display the results.

AlgoliaQuery searchQuery; //Implement as a global in the class.../**
* You can either use this line to implement it as a function so that
* it can be reused in other inherited superclass method OR use it as
* is in buildResults
*/
searchQuery = algolia.instance.index('YOUR_INDEX').search(query);...return Column(
children: <Widget>[
FutureBuilder(
future: searchQuery.getObjects(),
builder: (BuildContext context,
AsyncSnapshot<AlgoliaQuerySnapshot> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return new Text('Loading....');
break;
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Expanded(
child: ListView.separated(
separatorBuilder: (context, index) => Divider(
color: Colors.grey,
),
itemCount: snapshot.data.hits.length,
itemBuilder: (context, index) {
final AlgoliaObjectSnapshot result =
snapshot.data.hits[index];
return ListTile(
title: Text(result.data['name'],
style: TextStyle(
fontWeight: FontWeight.w700, fontSize: 18)),
subtitle: Text(result.data['country']),
);
},
),
);
}
}
},
)
],
);

Note: Do try to debug inside the builder to get what your snapshot data provides.

And the result,

With that, you can use SearchDelegate to display search results from Algolia. Cheers!

--

--

Mohammad Norhamizan
Flutter Community

I'm a programmer by heart | Contributing back to the community by sharing my knowledge and experience