Хорошо, здесь есть несколько хороших ответов о SOF, но они разделены, поэтому я попытаюсь ответить на ваш вопрос двумя подходами.
Но прежде всего, прежде чем писать код, я могу сказать вамчто этот код не работает, потому что в вашей ссылке вы не указали дочерний элемент, равный products
, очевидно, предполагая, что узел products
является прямым дочерним элементом корня базы данных Firebase.
фактический ответ:
Предполагая, что ваша структура базы данных выглядит следующим образом (в которой узел products
является прямым потомком вашей базы данных 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
Чтобы получитьПроизвольный продукт, используйте следующий код:
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);
Чтобы получить все продукты, вам нужно пройти через все дочерние элементы узла products
.Поэтому вызов child("products")
является обязательным.
Если вам нужно более одного случайного продукта, вы можете создать цикл и добавить столько случайных продуктов, сколько вы хотите, в свой randomProductList
.
Это называется классическим решением, и вы можете использовать его для узлов, которые содержат только несколько записей, но если вы боитесь получать огромное количество данных, я рекомендую вам этот второй подход.Это также включает небольшие изменения в вашей базе данных путем добавления нового узла с именем productIds
.Структура вашей базы данных должна выглядеть следующим образом:
Firebase-root
|
--- products
| |
| --- productIdOne
| | |
| | --- //details
| |
| --- productIdTwo
| |
| --- //details
|
--- productIds
|
--- productIdOne: true
|
--- productIdTwo: true
|
--- //And so on
Итак, как вы упомянули в своем вопросе, если вы хотите избежать загрузки всего узла products
, который содержит все продукты со всеми свойствами, вы должнысоздайте отдельный узел с именем productIds
.Таким образом, чтобы получить один продукт, вам нужно всего лишь загрузить простой узел, который содержит только идентификаторы продукта.
Эта практика называется денормализацией (дублирование данных) и является обычной практикой, когда речь идет о Firebase.Для лучшего понимания, я рекомендую вам посмотреть это видео, Денормализация нормальная с базой данных Firebase .
Но помните, как вы добавляете случайные продукты в этот новый созданный узел,таким же образом вам нужно удалить их, когда они больше не нужны.
Таким образом, чтобы получить случайный продукт, вам нужно дважды запросить базу данных.Пожалуйста, смотрите код ниже:
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);
Когда вы выполните запрос к базе данных Firebase, потенциально может быть несколько результатов.Таким образом, dataSnapshot
содержит список этих результатов.Даже если есть только один результат, объект dataSnapshot
будет содержать список из одного результата.