I have this database structure in firebase:
Its supposed to collect votes. I have several categories such as president, minister...etc. All people who vie for a "President" seat are listed using their unique keys, and Im trying to collect all voters emails.
This is my code:
public static void insertvote(String userkey, String categ, String candId) {
System.out.println("Returned candidate's userkey or ID: "+userkey);
System.out.println("Returned category: "+categ);
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference totalVotesRef = rootRef.child("votes").child(categ).child(candId);
Vote vote = new Vote(userkey);
totalVotesRef.setValue(vote.getVoterEmail());
}
The problem I have is that, when another user logs in and votes, instead of appending their email, its being overwritter to the existing email.
How can I resolve this?
Thanks
Instead of using setValue() at the location to collect emails, which always overwrites existing data, you should look into using push() first, which generates a new child using a random ID. You will want to become familiar with the documentation on working with lists of data, especially appending to a list of data.
totalVotesRef.push().setValue(vote.getVoterEmail())
Each email will appear under that randomly generated child value.
Related
I have this code:
public static void insertvote(String userkey, String categ, String candId) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference totalVotesRef = rootRef.child("votes").child(categ).child(candId);
Vote vote = new Vote(userkey);
totalVotesRef.push().setValue(vote.getVoterEmail());
}
It is supposed to insert votes into a firebase database, in a votes collections as below:
The idea is to ensure a voter only votes once due to integrity by checking if their email exists in the votes. However, as you can see, a voter can vote twice.
Is there a way I can make a function that checks whether the email exixts in the database, and if it does exist, tell the voter they cant vote twice?
Thanks in advance.
You should use the Firebase Auth UID of the current user as the name of the child key.
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
totalVotesRef.child(uid).setValue(vote.getVoterEmail());
I will give you an idea, think about it. If you use
Shared Preferences, you can put every e-mail address with a boolean flag(True/False - Voted/not). Then, you can call the Shared Preferences and check the boolean value of the flag for every e-mail address. So, if it’s true - don’t allow him to vote.
Wish I helped :)
Below is image representation of my firebase where user upload items under Electronics or Books category and also more categories. I want to build an activity with RecyclerView where I want to show the only item uploaded by a user. Since I'm using userid which is unique to push the details of the item inside a child, I can use userid to retrieve the items from child and display in firebase. But, how to search in each child from different category and show it in one RecyclerView.
My Code to Show the items from Electronics child is
dbreference = FirebaseDatabase.getInstance().getReference("Electronic").child("userid");
dbreference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
for (DataSnapshot data : snapshot.getChildren()) {
final Solditem b1 = data.getValue(SoldItem.class);
child_count++;
list.add(b1);
staggeredBooksAdapter.notifyDataSetChanged();
}
}
}
But I also would like to show the uploaded item by a user which equals to userid as key from Books in the same RecyclerView.
To delete an item from any category I use
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Query sellerquery = ref.child("Electronic").child("userid");
sellerquery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot appleSnapshot: dataSnapshot.getChildren()) {
appleSnapshot.getRef().removeValue();
}
}
}
To delete all the records of a user-uploaded item which key-value equals to userid, I need to repeat above code.
Is there any best and short method to delete all the records from any category which key-value equals to userid.
Thanks in advance.
While structuring your data in Firebase, you really need to think about the structure of your data very carefully so that you can run efficient queries on them. For example, in your case, you should have structured your data as follows.
userid
- Electronics
- Camera
- Cooker
- Books
- A brief history of time
- Inferno
Hence you could run your queries in such a way that, you could have all the items under a certain userid at once.
If you really need the structure that you have now for other sets of queries that you are planning to do in your application, think about replicating your data as well. That is, you might consider having duplicate entries of your data (replication) in different structure so that you can perform efficient queries. For example, the current structure of your data is suitable for the following query.
Get all userid under a specific category.
I think you have got my point. If you do not want to change the structure of your data then I am afraid that you might have to get all the data in your application from firebase first. Then you have to loop through the data yourself to find the elements that you actually needed.
Hope that helps!
I am trying to make app like Instagram with Firebase as a backend, while user adds the comment in any photo, new id is generated by Firebase now I want to add one child(likes) when user click on the like button in this randomly generated comment id but the issue is how to get that particular comment id?
There are two ways in which you can achieve this. So if you want to access a specific comment, you must know something that unique identifies that pcommentll. The first solution would be to store that random id in a variable in the exact moment when you are pushing a new comment to the database using the push() method. To get that id, you can use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
String commentId = rootRef
.child(UserId)
.child(PhotoId)
.child("comments")
.push()
.getKey();
You can also save that id inside the comment object if you need to use it later. So this is how it looks like in code:
Map<String, Object> map = new HashMap<>();
map.put("noOfLikes", 0);
map.put("commentId", commentId);
rootRef
.child(UserId)
.child(PhotoId)
.child("comments")
.child(commentId)
.updateChildren(map);
Once you have this key, you can use it in your reference to update the number of likes. This type of operation is usually done using Firebase transaction and for that I recommend see my answer from this post in which I have explained how to update a score property but same principle aplly in the case of likes.
The second approach would be to create an entire new top level collection like this:
Firebase-rot
|
--- comments
|
--- commentId
|
--- noOfLikes: 1
Using this solution it will be more easy for you to query the database becuase to get the number of likes you'll need only this simple reference:
DatabaseReference noOfLikesRef = rootRef
.child("comments")
.child(commentId)
.child("noOfLikes");
noOfLikesRef.addListenerForSingleValueEvent(/* ... */);
Try this:
Fetch the commentID before storing it like this:
String CommentId = myRef.push().getKey();
Save the ID along with comment data:
myRef.child(CommentId).set(yourValuesHashMap);
Now, when you retrieve the comments, you'll have the ID of each comment and you can use that the insert the likes.
I am trying to make app like Instagram with Firebase as a backend, while user adds the comment in any photo, new id is generated by Firebase now I want to add one child(likes) when user click on the like button in this randomly generated comment id but the issue is how to get that particular comment id?
There are two ways in which you can achieve this. So if you want to access a specific comment, you must know something that unique identifies that pcommentll. The first solution would be to store that random id in a variable in the exact moment when you are pushing a new comment to the database using the push() method. To get that id, you can use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
String commentId = rootRef
.child(UserId)
.child(PhotoId)
.child("comments")
.push()
.getKey();
You can also save that id inside the comment object if you need to use it later. So this is how it looks like in code:
Map<String, Object> map = new HashMap<>();
map.put("noOfLikes", 0);
map.put("commentId", commentId);
rootRef
.child(UserId)
.child(PhotoId)
.child("comments")
.child(commentId)
.updateChildren(map);
Once you have this key, you can use it in your reference to update the number of likes. This type of operation is usually done using Firebase transaction and for that I recommend see my answer from this post in which I have explained how to update a score property but same principle aplly in the case of likes.
The second approach would be to create an entire new top level collection like this:
Firebase-rot
|
--- comments
|
--- commentId
|
--- noOfLikes: 1
Using this solution it will be more easy for you to query the database becuase to get the number of likes you'll need only this simple reference:
DatabaseReference noOfLikesRef = rootRef
.child("comments")
.child(commentId)
.child("noOfLikes");
noOfLikesRef.addListenerForSingleValueEvent(/* ... */);
Try this:
Fetch the commentID before storing it like this:
String CommentId = myRef.push().getKey();
Save the ID along with comment data:
myRef.child(CommentId).set(yourValuesHashMap);
Now, when you retrieve the comments, you'll have the ID of each comment and you can use that the insert the likes.
Image here. Data does not sort accordingly like I wanted (O+, O+, A)
Currently, I have data that stored exactly like in the picture above, I want to make all the blood groups to be placed accordingly. For example, It will have only 0+ until the lists end. It will continue with different blood groups such A+, A- etc.
Can firebase actually sort that data? I was looking around, but could not find anything
Inside the Firebase Console, all the nodes are sorted lexicographically by key and this can't be changed.
However, when you retrieve the data on the client, you can choose to sort by one of the child properties. This way they will be sorted by the time they are shown to the client. For example:
// the reference to where your people are stored
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
// create the query
Query peopleBloodTypeQuery = mDatabase.child("people").orderByChild("bloodgroup");
// query the people
peopleBloodTypeQuery.addChildEventListener(new ChildEventListener() {
// add a child added listener
#Override public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
// do whatever here - I just print the key of each added child
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
}
});