How to Get Unique Random Product in Node Firebase

How to get unique random product in node Firebase?

Well, there are a few good answers here on SOF but are separated, so I will try to answer your question with two approaches.

But first of all, before writing some code, I can tell you that this code is not working because you are missig a child in your reference, which is products, obviously assuming that the products node is a direct child of your Firebase database root.

The actual answer:

Assuming that your database structure looks like this (in which the products node is a direct child of your Firebase database):

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

To get a random product, please use the following code:

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 productListSize = productList.size();
List<String> randomProductList = new ArrayList<>();

randomProductList.add(new Random().nextInt(productListSize)); //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);

In order to get all the products, you need to loop through all children of the products node. So a call to child("products") is mandatory.

If you want more then one random product, then you can create a loop and add as many random products as you want in your randomProductList.

This is called the classic solution and you can use it for nodes that contain only a few records but if you are afraid of getting huge amount of data then I'll recommend you this second approach. This also involves a little change in your database by adding a new node named productIds. Your database structure should look like this:

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

So as you mentioned in your question, if you want to avoid downloading the entire products node which contains all the products with all the properties, you have to create a separate node named productIds. So to get a single product, you'll need only to download a simple node that contains only the product ids.

This practice is called denormalization (duplicating data) and is a common practice when it comes to Firebase. For a better understanding, i recomand you see this video, Denormalization is normal with the Firebase Database.

But rememebr, in the way you are adding the random products in this new created node, in the same way you need to remove them when there are not needed anymore.

So to get the random product, you need to query your database twice. Please see the code below:

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 productListSize = productList.size();
List<String> randomProductList = new ArrayList<>(););

DatabaseReference productIdRef = rootRef.child("products").child(productIdsList.get(new Random().nextInt(int productListSize));
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);

When you execute a query against the Firebase Database, there will potentially be multiple results. So the dataSnapshot contains a list of those results. Even if there is only a single result, the dataSnapshot object will contain a list of one result.

retrieving a random node from firebase

Edit: 20th, August 2022

Maybe these other approaches will help:

  • How to get unique random product in node Firebase?

To solve this, please use the following lines of code:

long childrenCount = snapshot.getChildrenCount();
int count = (int) childrenCount;
int randomNumber = new Random().nextInt(count);

And then use a for loop to pull that value using the random number:

int i=0;
String themeTune; //Your random themeTune will be stored here
for (DataSnapshot snap : snapshot.getChildren()) {
if(i = randomNumber) {
themeTune = snap.getValue(String.class);
break;
}
i++;
}
plysound();

How to get random keys in Firebase Database without fetching all data from a reference node?

If you want to get a subset of the data from a large node into your application, and you cannot achieve that means by using a query to slice the data, it is quite common to duplicate the subset of the data into its own separate node.

An example (since you unfortunately remain rather generic in your question): if you have a list of user profiles (say /users), but are only trying to show a list of user names in your application, it is wasteful to retrieve the full user profiles. In such cases, it is common to create a node with just the user names and the UIDs (say /usernames).

You'll typically either create the derived list from a trusted environment (such as your development machine, a server you control, or Cloud Functions) or use security rules to ensure the data in the derived list remains in sync with the main list.

How do I generate a unique key for each message in Realtime Database?

Looking at the URL, is the key being added to root of db rather than inside of group ID node? If yes, then please make sure your database reference is correct. In your case:

String key = mDatabase.child("groupId").push().getKey()
mDatabase.child("groupId").child(key).setValue({}); //Set the required value

Other option as suggested in comments by @Louis is using UUIDs and that goes like this.

String key =  UUID.randomUUID().toString()
mDatabase.child("groupId").child(key).setValue({}); //Set the required value.

Let me know in comments if something is still going wrong.

How do i generate a unique id for a new node connected to a users id in firebase

You need to use push().

Assign a new id to your text element or whatever object you are trying to use in your app to represent/hold your id:

profid = findViewById(R.id.proffid );

Then assign this to your string:

proffessionid = profid.getText().toString().trim();

Then use push() to store and generate a unique id:

 proffRef.push().setValue(proffessionid);

For each entry under your proffRef,a new id will be generated.

You can also create a the node in such a way that the userid is directly attached to the new profession node as follows:

proffRef = FirebaseDatabase.getInstance().getReference().child("Professions").child(firebaseAuth.getCurrentUser().getUid());
proffRef.child("userid").setValue(firebaseAuth.getCurrentUser().getUid()
proffRef.child("profession").setValue(userProfession);

Then use push to generate a unique key when user saves the form.

proffRef.push().setValue(proffessionid);

I am not sure wether you want to display this id or not.But if you dont want to display the id,i would suggest you declare proffID in your pojo class/modal class and then use GetProffID.Alternatively,attach the id to your textview then set its visibility to invisible.
So in this instance,profid would be attached to your textview as follows:

<TextView
android:id="@+id/proffid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
/>

For aslong as you use the same reference for the node you are creating,all data the user enters in the form will be saved to that specific root node(Professions).

Another way to do this is to bind the id directly to the EditText:

Define your variables:

EditText userProfessionEdit;

give your variable an id for your UI

 userProfessionEdit = findViewById(R.id.UserProfession);

Get the String:

userProfession = userProfessionEdit.getText().toString().trim();

Bind the String to your id,generate the unique id.......:

 String value = userProfessionEdit.getText().toString();
String key = profid.getText().toString();
DatabaseReference childRef = proffRef.child(key);
childRef.push().setValue(value);

This will generate a unique id for each input without giving the id the child node of profid.

Get random user from Firebase

As far as I could understand, you want to pick a random user from all the list of users that you have in your firebase database. You can simply do that on the android side.

I think you already know how to get all the users from the firebase database. Store the users in a list. Then I would try to come up with a random function which could give me an index of the list randomly and I could pick that user from the list based on that random index.

The same implementation can go for selecting multiple users from that list as well.

I hope that helps.

Firebase: how to generate a unique numeric ID for key?

I'd suggest reading through the Firebase documentation. Specifically, see the Saving Data portion of the Firebase JavaScript Web Guide.

From the guide:

Getting the Unique ID Generated by push()

Calling push() will return a reference to the new data path, which you can use to get the value of its ID or set data to it. The following code will result in the same data as the above example, but now we'll have access to the unique push ID that was generated

// Generate a reference to a new location and add some data using push()
var newPostRef = postsRef.push({
author: "gracehop",
title: "Announcing COBOL, a New Programming Language"
});

// Get the unique ID generated by push() by accessing its key
var postID = newPostRef.key;

Source: https://firebase.google.com/docs/database/admin/save-data#section-ways-to-save

  • A push generates a new data path, with a server timestamp as its key. These keys look like -JiGh_31GA20JabpZBfa, so not numeric.
  • If you wanted to make a numeric only ID, you would make that a parameter of the object to avoid overwriting the generated key.
    • The keys (the paths of the new data) are guaranteed to be unique, so there's no point in overwriting them with a numeric key.
    • You can instead set the numeric ID as a child of the object.
    • You can then query objects by that ID child using Firebase Queries.

From the guide:

In JavaScript, the pattern of calling push() and then immediately calling set() is so common that we let you combine them by just passing the data to be set directly to push() as follows. Both of the following write operations will result in the same data being saved to Firebase:

// These two methods are equivalent:
postsRef.push().set({
author: "gracehop",
title: "Announcing COBOL, a New Programming Language"
});
postsRef.push({
author: "gracehop",
title: "Announcing COBOL, a New Programming Language"
});

Source: https://firebase.google.com/docs/database/admin/save-data#getting-the-unique-key-generated-by-push



Related Topics



Leave a reply



Submit