I'm trying to get the list of facet that I've configured as describe here. I use the new official Algolia package along with the unofficial for settings. I thought that use the official package would change the response. Despite in the console browser, every thing is display as attended the searchResponse.facets is always empty. Check the code below.
import 'dart:async';
import 'dart:io';
import 'package:algolia/algolia.dart';
import 'package:algolia_helper_flutter/algolia_helper_flutter.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:masterecommerce/src/constants/app_sizes.dart';
import 'package:masterecommerce/src/exceptions/app_exception.dart';
import 'package:masterecommerce/src/features/menu/presentation/search_header.dart';
import 'package:masterecommerce/src/features/products/domain/algolia_output.dart';
import 'package:masterecommerce/src/features/products/domain/algolia_params.dart';
import '../constants/credentials.dart';
import '../features/products/domain/product.dart';
import 'firestore_service.dart';
final searchResponseProvider = StateProvider.autoDispose<SearchResponse>((ref) {
return SearchResponse({});
});
final searchStateProvider = StateProvider.autoDispose<SearchState>((ref) {
return const SearchState(indexName: kIndexName);
});
final algoliaInputProvider = StateProvider.autoDispose<AlgoliaInput>((ref) {
return const AlgoliaInput();
});
final algoliaControllerProvider = StateNotifierProvider.autoDispose<
AlgoliaController, AsyncValue<List<Product>>>((ref) {
return AlgoliaController(
ref: ref, algoliaInput: ref.watch(algoliaInputProvider));
});
final algoliaControllerSearchProvider = StateNotifierProvider.autoDispose<
AlgoliaController, AsyncValue<List<Product>>>((ref) {
return AlgoliaController(
ref: ref,
algoliaInput: AlgoliaInput(
query: ref.watch(currentQuerySearchProvider), hitsPerPage: 3));
});
class AlgoliaController extends StateNotifier<AsyncValue<List<Product>>> {
StreamSubscription? subResponses;
StreamSubscription? subSearchState;
late HitsSearcher searcher;
late Algolia algoliaForSettings;
final Ref ref;
final AlgoliaInput algoliaInput;
AlgoliaController({required this.ref, required this.algoliaInput})
: super(const AsyncLoading()) {
algoliaForSettings = const Algolia.init(
applicationId: algoliaKeyAppId, apiKey: algoliaKeyCustom);
searcher = HitsSearcher(
applicationID: algoliaKeyAppId,
apiKey: algoliaKeyCustom,
indexName: kIndexName,
);
subResponses = searcher.responses.handleError((onError) {
print(onError);
state = AsyncError(onError);
}).listen((searchResponse) {
print(searchResponse.facets);
print(searchResponse.raw["facets"]);
ref.read(searchResponseProvider.state).update((state) => searchResponse);
final products = searchResponse.hits
.map((e) => Product.fromMapAlgolia(e.cast()))
.toList();
if (mounted) {
state = AsyncValue<List<Product>>.data(products);
}
});
subSearchState = searcher.state.handleError((onError) {
print(onError);
state = AsyncError(onError);
}).listen((searchState) {
ref.read(searchStateProvider.state).update((state) => searchState);
});
_newAlgoliaState(algoliaInput: algoliaInput);
}
@override
void dispose() {
searcher.dispose();
subResponses?.cancel();
subSearchState?.cancel();
super.dispose();
}
Future<void> _newAlgoliaState({required AlgoliaInput algoliaInput}) async {
state = const AsyncLoading();
final algoliaOutput = algoliaInput.toAlgoliaOutput();
await _setAlgoliaRanking(algoliaOutput: algoliaOutput);
if (!mounted) {
return;
}
searcher.connectFilterState(algoliaOutput.filterState);
searcher.applyState((state) => algoliaOutput.toSearchState());
}
Future<void> _setAlgoliaRanking(
{required AlgoliaOutput algoliaOutput}) async {
AlgoliaIndexReference algoliaIndexReference =
algoliaForSettings.instance.index("products");
final ranking = algoliaOutput.ranking;
if (ranking != null && ranking.isNotEmpty) {
AlgoliaTask algoliaTask =
await algoliaIndexReference.settings.setRanking([
...ranking,
"typo",
"geo",
"words",
"filters",
"proximity",
"attribute",
"exact",
"custom",
]).setSettings();
await algoliaTask
.waitTask()
.timeout(const Duration(seconds: timeOutSecond))
.catchError((onError) {
if (onError is SocketException) {
throw const AppException.noInternet();
} else if (onError is TimeoutException) {
throw const AppException.timeOut();
} else {
throw const AppException.unknown();
}
});
}
final customRanking = algoliaOutput.customRanking;
if (customRanking != null && customRanking.isNotEmpty) {
final AlgoliaTask algoliaTask = await algoliaIndexReference.settings
.setCustomRanking(customRanking)
.setSettings();
await algoliaTask
.waitTask()
.timeout(const Duration(seconds: timeOutSecond))
.catchError((onError) {
if (onError is SocketException) {
throw const AppException.noInternet();
} else if (onError is TimeoutException) {
throw const AppException.timeOut();
} else {
throw const AppException.unknown();
}
});
}
}
}