4

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.

enter image description here

I want to search by the name parameter.

enter image description here

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Alpit Panchal
  • 709
  • 1
  • 7
  • 25
  • Do you want to search for documents where the `name` field exactly matches the search term or do you want to a full text search (https://firebase.google.com/docs/firestore/solutions/search) ? – Victor Eronmosele Jul 02 '21 at 11:33
  • Thanks for response suppose I have many records so if I have searched the "al" so all text will show who starts with and matches with "al" text. – Alpit Panchal Jul 02 '21 at 11:59
  • Okay, that's a full-text search. Please visit the link in my first comment to see how it is implemented. You will need a third-party search service like Algolia. – Victor Eronmosele Jul 02 '21 at 12:02
  • I have checked the URL as you suggest but can't understand this if you have any demo related to this so please share with me. And I have also searched the (https://pub.dev/packages/firestore_search) plugin so can you please suggest is use full or not. – Alpit Panchal Jul 02 '21 at 12:06
  • Checkout https://dev.to/samarthagarwal/full-text-search-in-flutter-with-algolia-3kni for the demo. – Victor Eronmosele Jul 02 '21 at 13:16

4 Answers4

17

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.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
4

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();
  }
})
Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
0

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.

Tarik Huber
  • 7,061
  • 2
  • 12
  • 18
0

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()
Rohan Arora
  • 303
  • 2
  • 12