Reputation: 1057
I want to implement search functionality using cloud Firestore by a query but not getting any query related to fetch data. I have searched many things on google but everywhere the only suggestion is first to get all data from cloud Firestore then searches locally. I have checked the where condition inside of the query but not finding any condition like "start with" etc.
I want to search by the name parameter.
Upvotes: 8
Views: 12721
Reputation: 541
for firebase searching in the docs with a String query
collectionRef.where(
'name',
isGreaterThanOrEqualTo: query.isEmpty ? 0 : query,
isLessThan: query.isEmpty
? null
: query.substring(0, query.length - 1) +
String.fromCharCode(
query.codeUnitAt(query.length - 1) + 1,
),
)
.snapshots()
Upvotes: 1
Reputation: 600006
Firestore does not have built-in full-text-search capabilities. The only two query operators I commonly use for searching text fields are:
Using isEqualTo:
to find documents where the field matches the value exactly.
Using isGreaterThanOrEqualTo:
and isLessThanOrEqualTo:
(or startAt:
and endAt:
) to search for documents where the field starts with a specific value.
For example, to search for all documents where name
starts with al
,
you'd use collectionRef.where("name", isGreaterThanOrEqualTo: "al").where("name", isLessThanOrEqualTo: "al\uf7ff")
. The \uf7ff
here is just the last known Unicode character, so that the query stops returning results after dealing with every al
.
If you want any other text search operations, you'll need to use an additional product for that - such the ones for which the process is documented here.
Upvotes: 21
Reputation: 671
this code will be very super helpful in searching text by using firestone flutter
StreamBuilder(
stream: ( searchtxt!= "" && searchtxt!= null)?FirebaseFirestore.instance.collection("addjop").where("specilization",isNotEqualTo:searchtxt).orderBy("specilization").startAt([searchtxt,])
.endAt([searchtxt+'\uf8ff',])
.snapshots()
:FirebaseFirestore.instance.collection("addjop").snapshots(),
builder:(BuildContext context,snapshot) {
if (snapshot.connectionState == ConnectionState.waiting &&
snapshot.hasData != true) {
return Center(
child:CircularProgressIndicator(),
);
}
else
{retun widget();
}
})
Upvotes: 5
Reputation: 7418
There is a way for short strings like a name. We use it quite often in our apps. You can split the name into small parts and add them to an array. To search for the name with a full text search wait to have at least 3 letters and check then if the combination of letters is part of the array using the array-contains-any
query.
The split to array code:
const MAPPING_TABLE = {
à: 'a',
á: 'a',
â: 'a',
ã: 'a',
å: 'a',
æ: 'ae',
ç: 'c',
è: 'e',
é: 'e',
ê: 'e',
ë: 'e',
ì: 'i',
í: 'i',
î: 'i',
ï: 'i',
ñ: 'n',
ò: 'o',
ó: 'o',
ô: 'o',
õ: 'o',
ù: 'u',
ú: 'u',
û: 'u',
ý: 'y',
ÿ: 'y',
}
function splitStringToArray(stringToSplit) {
const listCharacters = stringToSplit.split('')
var output = []
//replace special Characters
for (var i = 0; i < listCharacters.length; i++) {
if (MAPPING_TABLE[listCharacters[i]] != null) {
listCharacters[i] = MAPPING_TABLE[listCharacters[i]]
}
}
for (var i = 0; i < listCharacters.length; i++) {
var temp = [listCharacters[i]]
for (var j = i + 1; j < listCharacters.length; j++) {
temp.push(listCharacters[j])
const joinedString = temp.join('').toLowerCase()
if (joinedString.length > 2) {
output.push(joinedString)
}
}
}
return output
}
export default splitStringToArray
And here is a query to search for the name:
ref = ref.where("search", "array-contains-any", [value.toLowerCase()]);
const snap = await ref.limitToLast(20).get();
I would also limit the results to a realisting amount of elements.
Upvotes: 0