java android firebase firebase-realtime-database

java - ¿Cómo obtener un producto aleatorio único en el nodo Firebase?



android firebase-realtime-database (1)

Datos:

- products - -L74Pc7oVY22UsCETFBv - name: "gjwj" - category: "hreggrrg" - location: "vjhiwehifwe" - price: 44 - color: fassaf - -L74uJ7oVYcVNyCteFBz - name: "uygfwh" - category: "hhhjwwwom" - location: "pervrr" - price: 33 - color: yrtrr ......................

Tengo muchos productos en productos de nodo, más de 1000 productos. Puedo mostrar todo en ListView . Quiero mostrar solo un usuario aleatorio único, como resaltados, pero no descargar todos, solo uno.

Código:

ValueEventListener v = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { for(DataSnapshot child : dataSnapshot.getChildren()) { String name = (String) child.child("name").getValue().toString(); Toast.makeText(MainActivity.this, name, Toast.LENGTH_SHORT).show(); //How to get????? } } @Override public void onCancelled(DatabaseError databaseError) {} }; FirebaseDatabase.getInstance().getReference().addListenerForSingleValueEvent(v);

¿Cómo obtener un producto aleatorio único en el nodo Firebase?


Bueno, hay algunas buenas respuestas aquí en SOF pero están separadas, así que intentaré responder tu pregunta con dos enfoques.

Pero antes que nada, antes de escribir algo de código, puedo decirle que este código no funciona porque está faltando a un niño en su referencia, que es products , obviamente, asumiendo que el nodo de products es un hijo directo de la base de datos de su base de datos Firebase.

La respuesta real:

Suponiendo que la estructura de su base de datos tenga este aspecto (en el que el nodo de products es un elemento secundario directo de su base de datos Firebase):

Firebase-root | --- products | --- productIdOne | | | --- name: "gjwj" | | | --- category: "hreggrrg" | | | --- location: "vjhiwehifwe" | | | --- price: 44 | | | --- color: "fassaf" | --- productIdTwo | | | --- name: "uygfwh" | | | --- category: "hhhjwwwom" | | | --- location: "pervrr" | | | --- price: 33 | | | --- color: "yrtrr" | --- //And so on

Para obtener un producto al azar, utilice el siguiente código:

List<String> randomProductList = new ArrayList<>(); ListView listView = (ListView) findViewById(R.id.list_view); ArrayAdapter arrayAdapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, randomProductList); listView.setAdapter(arrayAdapter); DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); DatabaseReference productsRef = rootRef.child("products"); //Added call to .child("products") ValueEventListener valueEventListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { List<String> productList = new ArrayList<>(); for(DataSnapshot ds : dataSnapshot.getChildren()) { String name = ds.child("name").getValue(String.class); productList.add(name); } int productCount = productList.size(); int randomNumber = new Random().nextInt(productCount); randomProductList.add(productList.get(randomNumber)); //Add the random product to list arrayAdapter.notifyDatasetChanged(); } @Override public void onCancelled(DatabaseError databaseError) { Log.d(TAG, "Error: ", task.getException()); //Don''t ignore errors! } }; productsRef.addListenerForSingleValueEvent(valueEventListener);

Para obtener todos los productos, debe recorrer todos los elementos secundarios del nodo de products . Por lo tanto, una llamada al child("products") es obligatoria.

Si desea más de un producto aleatorio, puede crear un bucle y agregar tantos productos aleatorios como desee en su randomProductList productos aleatoria.

Esto se llama la solución clásica y puede usarla para nodos que contienen solo unos pocos registros, pero si tiene miedo de obtener una gran cantidad de datos, le recomendaré este segundo enfoque. Esto también implica un pequeño cambio en su base de datos al agregar un nuevo nodo llamado productIds . La estructura de su base de datos debería verse así:

Firebase-root | --- products | | | --- productIdOne | | | | | --- //details | | | --- productIdTwo | | | --- //details | --- productIds | --- productIdOne: true | --- productIdTwo: true | --- //And so on

Entonces, como mencionó en su pregunta, si desea evitar descargar el nodo completo de products que contiene todos los productos con todas las propiedades, debe crear un nodo separado denominado productIds . Por lo tanto, para obtener un solo producto, solo necesitará descargar un nodo simple que contenga solo los identificadores del producto.

Esta práctica se denomina denormalización (duplicación de datos) y es una práctica común cuando se trata de Firebase. Para una mejor comprensión, le recomiendo que vea este video, la desnormalización es normal con la base de datos Firebase .

Pero recuerde, de la manera en que agrega los productos aleatorios en este nuevo nodo creado, de la misma manera que necesita eliminarlos cuando ya no sean necesarios.

Entonces, para obtener el producto aleatorio, necesita consultar su base de datos dos veces. Por favor, consulte el siguiente código:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); DatabaseReference productIdsRef = rootRef.child("productIds"); ValueEventListener valueEventListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { List<String> productIdsList = new ArrayList<>(); for(DataSnapshot ds : dataSnapshot.getChildren()) { String productId = ds.getKey(); productIdsList.add(productId); } int productCount = productIdsList.size(); int randomNumber = new Random().nextInt(productCount); DatabaseReference productIdRef = rootRef.child("products").child(productIdsList.get(randomNumber)); ValueEventListener eventListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { String name = dataSnapshot.child("name").getValue(String.class); Log.d("TAG", name); } @Override public void onCancelled(DatabaseError databaseError) { Log.d(TAG, "Error: ", task.getException()); //Don''t ignore errors! } }; productIdRef.addListenerForSingleValueEvent(eventListener); } @Override public void onCancelled(DatabaseError databaseError) { Log.d(TAG, "Error: ", task.getException()); //Don''t ignore errors! } }; productIdsRef.addListenerForSingleValueEvent(valueEventListener);

Cuando ejecute una consulta en la base de datos de Firebase, potencialmente habrá múltiples resultados. Así que el dataSnapshot contiene una lista de esos resultados. Incluso si solo hay un resultado único, el objeto dataSnapshot contendrá una lista de un resultado.