This post uses javascript, however you can apply this concept to any firebase client.
You can query firestore (a firebase db) quite easily. But when it comes to string search; they dropped the ball and send you to third party search solutions. There is nothing wrong with that if your project needs a full text search; but what if you just want a simple string starts with search (like*)? hopefully firestore will do something about this.
For now, let me share what I have done for IPster. IPster app needed a simple search by first name. And for now we didn't wanted to invest in or use systems like Algolia (nothing against Algolia, I love the product and we probably be using it in the future).
So how do you search firestore for something like 'get me all documents where name starts with sam'
Using firebase javascript client
This should work for most languages.
searchTerm = searchTerm.toLowerCase();
strlength = searchTerm.length;
strFrontCode = searchTerm.slice(0, strlength-1);
strEndCode = searchTerm.slice(strlength-1, searchTerm.length);
// This is an important bit..
endCode = strFrontCode + String.fromCharCode(strEndCode.charCodeAt(0) + 1);
Query using the start and end codes and you will be able to get the same results as you would in traditional databases LIKE 'a%'
db.collection('collectionName').where('fieldName', '>=', searchTerm).where('fieldName', '<', endCode).limit(10);
That's it. You should be able to do simple 'starts with' search now. It's a good practice to limit the result set since Firebase will charge you for all documents returned. And if you are using firebase in an open project, you can also setup rules to limit the query results.
Using Angularfire
For IPster we are using Angular fire which makes dealing with complex queries a little easier. Let me give you an example of how we implemented a simple starts with query together with Observable and switchMap
import { Observable, Subject, combineLatest } from 'rxjs';
import { switchMap } from 'rxjs/operators';
startCode = new Subject();
endCode = new Subject();
// Once only, in your constructor or init
searchResults = combineLatest(
this.startCode,
this.endCode
).pipe(
switchMap(([startCode, endCode]) =>
fireStore.collection('collectionName', ref => ref.where('fieldName', '>=', startCode).where('fieldName', '<', endCode).limit(10)).valueChanges()
)
);
// Prepare endCode and searchTerm as described in the previous section
// Now you can change the query and get the results (search as you type etc..)
this.startCode.next(searchTerm);
this.endCode.next(endCode);
There you have it.
Top comments (0)