findBySearchTermWithConverter method

Future<FeedbackResponse<List<T>>> findBySearchTermWithConverter({
  1. required String searchTerm,
  2. required String searchField,
  3. required SearchTermType searchTermType,
  4. bool doSearchNumberEquivalent = false,
  5. int? limit,
})

Finds documents based on a given searchTerm and searchField.

The searchTermType defines the type of field that is specified as searchField. You are able to search a SearchTermType.startsWith field for direct hits or for a SearchTermType.arrayContains that may contain the searchField.

This method returns data in the form of a list of T. Make sure to have specified the _toJson and _fromJson methods or else the FirestoreApi will not now how to convert the data.

If _tryAddLocalId is true then your data will also contain a local id field based on the _idFieldName specified in the constructor. Add this id field to your T and you will have easy access to the document id at any time.

If _tryAddLocalDocumentReference is true then your data will also contain a local reference field based on the _documentReferenceFieldName specified in the constructor. Add this reference field to your T and you will have easy access to the document reference at any time.

If you rather want to retrieve data in the raw form of a List<Map<String, dynamic>> consider using the findBySearchTerm method instead.

Implementation

Future<FeedbackResponse<List<T>>> findBySearchTermWithConverter({
  required String searchTerm,
  required String searchField,
  required SearchTermType searchTermType,
  bool doSearchNumberEquivalent = false,
  int? limit,
}) async {
  try {
    _log.info('🔥 Searching ${_collectionPath()} '
        'without converter, '
        'searchTerm: $searchTerm, '
        'searchField: $searchField, '
        'searchTermType: ${searchTermType.name} and '
        'limit: $limit..');
    collectionReferenceQuery(Query<T> collectionReference) => searchTermType.isArray
        ? limit == null
            ? collectionReference.where(
                searchField,
                arrayContainsAny: [searchTerm, ...searchTerm.split(' ')],
              )
            : collectionReference.where(
                searchField,
                arrayContainsAny: [searchTerm, ...searchTerm.split(' ')],
              ).limit(limit)
        : limit == null
            ? collectionReference.where(
                searchField,
                isGreaterThanOrEqualTo: searchTerm,
                isLessThan: '$searchTerm\uf8ff',
              )
            : collectionReference
                .where(
                  searchField,
                  isGreaterThanOrEqualTo: searchTerm,
                  isLessThan: '$searchTerm\uf8ff',
                )
                .limit(limit);
    final result = (await collectionReferenceQuery(
      findCollectionWithConverter(),
    ).get())
        .docs
        .map((e) => e.data())
        .toList();
    if (doSearchNumberEquivalent) {
      try {
        final numberSearchTerm = double.tryParse(searchTerm);
        if (numberSearchTerm != null) {
          collectionReferenceQuery(Query<T> collectionReference) => searchTermType.isArray
              ? limit == null
                  ? collectionReference.where(
                      searchField,
                      arrayContainsAny: [numberSearchTerm],
                    )
                  : collectionReference.where(
                      searchField,
                      arrayContainsAny: [numberSearchTerm],
                    ).limit(limit)
              : limit == null
                  ? collectionReference.where(
                      searchField,
                      isGreaterThanOrEqualTo: numberSearchTerm,
                      isLessThan: numberSearchTerm + 1,
                    )
                  : collectionReference
                      .where(
                        searchField,
                        isGreaterThanOrEqualTo: numberSearchTerm,
                        isLessThan: numberSearchTerm + 1,
                      )
                      .limit(limit);
          final numberResult = (await collectionReferenceQuery(
            findCollectionWithConverter(),
          ).get())
              .docs
              .map(
                (e) => e.data(),
              )
              .toList();
          result.addAll(numberResult);
        }
      } catch (error, stackTrace) {
        _log.error(
          '${error.runtimeType} caught while trying to search for number equivalent of $searchTerm',
          error: error,
          stackTrace: stackTrace,
        );
      }
    }
    _logResultLength(result);
    return _responseConfig.searchSuccessResponse(isPlural: result.isPlural, result: result);
  } catch (error, stackTrace) {
    _log.error(
        '🔥 '
        'Unable to find ${_collectionPath()} documents with '
        'search term: $searchTerm and '
        'field: $searchField}',
        error: error,
        stackTrace: stackTrace);
    return _responseConfig.searchFailedResponse(isPlural: true);
  }
}