android - ¿Es posible usar la consulta Algolia en FirestoreRecyclerOptions?
google-cloud-firestore (2)
Para permitir que mi usuario realice búsquedas más complejas, estoy trabajando con Algolia.
com.algolia.search.saas.Query algolia_query =
new com.algolia.search.saas.Query(mLastQuery)
.setAttributesToRetrieve("content")
.setAttributesToRetrieve("category")
.setHitsPerPage(10);
index.searchAsync(algolia_query, new CompletionHandler() {
@Override
public void requestCompleted(JSONObject jsonObject, AlgoliaException e) {
Log.d("algolia", jsonObject.toString());
}
});
Me gustaría convertir este jsonObject en algo compatible con
FirestoreRecyclerOptions
para poder usar
FirestoreRecyclerAdapter
Gracias !
No hay conexión entre FirebaseUI y Algolia. Si desea mostrar los resultados de búsqueda de Algolia, tendrá que construir un adaptador usted mismo.
Puedes considerar usar
FirebaseUI''s
FirebaseIndexedArray
para inspirarte.
Pero una advertencia justa: tanto sus componentes internos como las modificaciones necesarias están bastante involucrados.
Para una mejor comprensión, intentaré explicar esto con un ejemplo.
Supongamos que tenemos un objeto
FirebaseFirestore
que apunta a la referencia raíz de la base de datos y un objeto
CollectionReference
que apunta a una colección llamada
products
.
Y para eso podemos usar las siguientes dos líneas de código:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference productsRef = rootRef.collection("products");
Supongamos también que tenemos una base de datos de Cloud Firestore que se ve así:
Firestore-root
|
--- products
|
--- productIdOne
| |
| --- productName: "Milk"
|
--- productIdTwo
|
--- productName: "Soy Milk"
|
--- productIdThree
|
--- productName: "Bacon"
Para lograr esta estructura, agreguemos estos productos a la base de datos y también los índices correspondientes, usando el código a continuación:
Map<String, Object> mapOne = new HashMap<>();
mapOne.put("productName", "Milk");
Map<String, Object> mapTwo = new HashMap<>();
mapTwo.put("productName", "Soy Milk");
Map<String, Object> mapThree = new HashMap<>();
mapThree.put("productName", "Bacon");
WriteBatch writeBatch = rootRef.batch();
writeBatch.set(productsRef.document(), mapOne);
writeBatch.set(productsRef.document(), mapTwo);
writeBatch.set(productsRef.document(), mapThree);
writeBatch.commit();
Client client = new Client(YourApplicationID, YourAPIKey);
Index index = client.getIndex("products");
List<JSONObject> productList = new ArrayList<>();
productList.add(new JSONObject(mapOne));
productList.add(new JSONObject(mapTwo));
productList.add(new JSONObject(mapThree));
index.addObjectsAsync(new JSONArray(productList), null);
Supongamos también que tenemos 2 vistas en
EditText
archivo de diseño, un
EditText
y un
ListView
.
EditText editText = findViewById(R.id.edit_text);
ListView listView = findViewById(R.id.list_view);
Para mostrar realmente esos productos en nuestro
ListView
, usemos el siguiente código:
productsRef.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
List<String> list = new ArrayList<>();
for (DocumentSnapshot document : task.getResult()) {
list.add(document.getString("productName"));
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, list);
listView.setAdapter(arrayAdapter);
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
Para filtrar los productos de acuerdo con el texto que
EditText
en nuestro
EditText
, necesitamos agregar un
TextChangedListener
como este:
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
@Override
public void afterTextChanged(Editable editable) {
Query query = new Query(editable.toString())
.setAttributesToRetrieve("productName")
.setHitsPerPage(50);
index.searchAsync(query, new CompletionHandler() {
@Override
public void requestCompleted(JSONObject content, AlgoliaException error) {
try {
JSONArray hits = content.getJSONArray("hits");
List<String> list = new ArrayList<>();
for (int i = 0; i < hits.length(); i++) {
JSONObject jsonObject = hits.getJSONObject(i);
String productName = jsonObject.getString("productName");
list.add(productName);
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, list);
listView.setAdapter(arrayAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
});
Entonces, para que funcione, hemos creado un nuevo objeto adaptador.
Esto significa que para cada carácter que
EditText
en
EditText
, creamos un nuevo adaptador y
EditText
este adaptador con los resultados que provienen de la base de datos.
Y para responder a su pregunta, para lograr lo que desea, no tiene que cambiar el objeto
JSONObject
, debe crear un nuevo objeto de consulta que se debe pasar al método
setQuery()
que se llama en el objeto
FirestoreRecyclerOptions
.
Acabo de darte un ejemplo más simple para entender el flujo.
Para más información, también te recomiendo que veas este
video
.