android google-cloud-firestore

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 .