Get a specific nested child and count it - java

I making an Attendance App.
In the app there is a function to know how many event an users already attend and what event they attend.
What i want is something like this (i dont know if it work or there is a better way):
private void fetchSpecificEvent() {
//Fetch event that user already attend
FirebaseRecyclerOptions<ModelEvent> options = new FirebaseRecyclerOptions.Builder<ModelEvent>()
.setQuery(referenceForSpecificEvent, snapshot -> new ModelEvent(
Objects.requireNonNull(snapshot.child("eventID").getValue()).toString(),
...
...
...
)
.build();
...
}
private void getAttendanceCount(){
//Get how many event user already attend
referenceForCount.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
attendanceCount = (int) snapshot.getChildrenCount();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
The main problem is i dont know what reference i use on: referenceForSpecificEvent and referenceForCount
This the JSON:
This the full JSON : https://pastebin.com/k65jhMUC
Sorry for the title, i dont know the keyword for it.

I found the way to do it. Probably not the best (because i cant really explain what i want) but it works.
reference = FirebaseDatabase.getInstance().getReference().child("Attendance");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
for (DataSnapshot eventSnapshot: dataSnapshot.getChildren()) {
//Get Event ID
Log.i(TAG, eventSnapshot.getKey());
for (DataSnapshot userSnapshot: dataSnapshot.child(Objects.requireNonNull(eventSnapshot.getKey())).getChildren()) {
//Get User ID
//Log.i(TAG, userSnapshot.getKey());
if(Objects.equals(userSnapshot.getKey(), stringEmail)){
intCount++;
listEvent.add(eventSnapshot.getKey());
}
}
}
}
else{
Log.i(TAG, "No Value Found");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.d(TAG, error.getMessage()); //Don't ignore errors!
}
});

Related

How can I change the value of child in Firebase database?

I want to change the value of child "toggleStatus" under Reference "BetSlip" as shown below. The already set value is "on" so I want such that when I click the button the value of "toggleStatus" is changed to "off"
BetSlipActivity.toggleCollapse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String timeStamp = betSlip.get(position).getTimeStamp();
String toggleStatus = betSlip.get(position).getToggleStatus();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("BetSlip");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds: snapshot.getChildren()) {
String timestamp = ""+ ds.child("timeStamp").getValue();
String toggleStatus = ""+ ds.child("toggleStatus").getValue();
if (timeStamp.equals(timestamp) && toggleStatus.equals("on")) {
//set value to off
}
if (timeStamp.equals(timestamp) && toggleStatus.equals("off")) {
//set value to on
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
});
If you've got the DataSnapshot for a path in the database, it's easy to get the DatabaseReference that you need to update it:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("BetSlip");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds: snapshot.getChildren()) {
String timestamp = ""+ ds.child("timeStamp").getValue();
String toggleStatus = ""+ ds.child("toggleStatus").getValue();
if (timeStamp.equals(timestamp) && toggleStatus.equals("on")) {
ds.child("toggleStatus").getRef().setValue("off");
}
if (timeStamp.equals(timestamp) && toggleStatus.equals("off")) {
ds.child("toggleStatus").getRef().setValue("on");
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
Since you're updating the node based on its existing value, strictly speaking you might need to use a transaction for it.

Running firebase database reference object inside a loop. How can I exit the loop if datasnapshot found. Below is my code

This is my code. I need to exit from for loop while data snapshot exists or not. I have tried with a listener interface that will invoke a call back when a data snapshot found or not. However, this listener is invoking only after all iterations. I need to exit the loop immediately. I even tried saving a boolean value in a shared preference and retrieve that value and check if it is true then only run for loop. But that approach is also not working. What is happening here, for loop is iterating through all users then only I'm getting the result from firebase background task.
private void createBranchAndAddUser(final String userKey) {
// Getting the referring user from DB
reference.child("User").orderByChild("uid").equalTo(referredBy)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot dst : dataSnapshot.getChildren()) {
referrerKey = dst.getKey(); // Got referring user firebase key
// Getting referring user branches.
reference.child("User").child(referrerKey).child("Branch")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// Branch found under referrer.
if (dataSnapshot.getChildrenCount() == 1) {
// One branch found under referrer. Adding one more under referrer.
Branch branch = new Branch();
branch.setUser_key(userKey);
reference.child("User").child(referrerKey).child("Branch").push().setValue(branch);
} else { // Two branch found under referring user. So moving to the next step.
// GETTING COMPLETE LIST OF USERS WHO ARE REFERRED BY REFERRING USER. (2: Step -> 2)
reference.child("User").orderByChild("referredBy").equalTo(referredBy).
addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull final DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// THIS IS THE LOOP I WANT ESCAPE.
for (DataSnapshot ds : dataSnapshot.getChildren()) {
User user = ds.getValue(User.class); // Got all users under referrer.
final String childUserKey = ds.getKey(); // Got firebase key of first child user under referrer.
Log.e(TAG, "isBranch Created " + isBranchCreated);
assert childUserKey != null;
reference.child("User").child(childUserKey).child("Branch")// getting branches of child user. (2: Step -> 3)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
if (dataSnapshot.getChildrenCount() == 1) {
// One branch found under child user.
Branch branch = new Branch();
branch.setUser_key(userKey);
reference.child("User").child(childUserKey).child("Branch").push().setValue(branch);
// need break the loop here, escape from the loop
isBranchCreated = "YES";
}
} else {
Branch branch = new Branch();
branch.setUser_key(userKey);
reference.child("User").child(childUserKey).child("Branch").push().setValue(branch);
// or break the loop here and escape from the loop.
isBranchCreated = "YES";
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.e(TAG, "onCancelled: " + databaseError.getMessage());
}
});
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.e(TAG, "onCancelled: " + databaseError.getMessage());
}
});
}
} else {
// No branch found under referrer.
Branch branch = new Branch();
branch.setUser_key(userKey);
reference.child("User").child(referrerKey).child("Branch").push().setValue(branch);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.e(TAG, "onCancelled: " + databaseError.getMessage());
}
});
}

Detect value change with firebase ValueEventListener

I am trying to detect value change from my Firebase Database. Here is my code for initializing the ValueEventListener:
valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
try {
String customerLocation = String.valueOf(dataSnapshot.getValue());
Point customerPoint = locationFounder.getPoint(customerLocation);
if (customerPoint != null) {
databaseReference.child("isActive").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
boolean isActive = Boolean.valueOf(String.valueOf(dataSnapshot.getValue()));
displayPopUp(isActive, customerPoint, customerLocation);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
} catch (Exception e) {
Log.d("Listener",e.toString());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
destinationReference.addValueEventListener(valueEventListener);
Problem occurs when I want to call this listener in my activity. I've been trying with this:
destinationListener.getValueEventListener().onDataChange(REQUIRED_SNAPSHOT);
I do not know how can I get datasnapshot which is required for onDataChange. I would like to get this work with ValueEventListener, not ChildEventListener, if possible. However, I am not pretty sure that this is the right way of trying to detect value change. If there is any other way that will work properly, I'd like to know about it.
There is nothing built to the Firebase Realtime Database to tell you what specific data under the snapshot has changed in the onDataChange method.
If you want to know what specific property has change, you'll need to:
Keep the snapshot that you get in onDataChange in a field.
When onDataChange gets called, compare the data in the new snapshot with the data in the field.
Say that you have a reference on a node in your JSON, and under that node is a status property, and you want to both listen to the entire node, and detect if the status has changed.
You'd do that with something like:
// Add a field to your class to keep the latest snapshot
DataSnapshot previousSnapshot;
// Then add your listener
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
bool wasActive = false;
if (previousSnapshot != null && previousSnapshot.child("status").exists()) {
wasActive = dataSnapshot.child("status").getValue(Boolean.class);
}
boolean isActive = dataSnapshot.child("status").getValue(Boolean.class);
if (isActive <> wasActive) {
... the user's status changed
}
previousSnapshot = dataSnapshot;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});

How to check if value exists in firebase databse

I have this Database:
I want to find out if a Email (value in database) already exists. So I have to iterate through each child of "email" and check if the value equals to the String inputMail.
I tried the following Code, but It doesn´t work, can anybody help me please? Thank u
final String input_mail = et_email.getText().toString();
DatabaseReference email = FirebaseDatabase.getInstance().getReference().child("email");
email.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String emailVal = ds.getValue(String.class);
if (emailVal.equals(input_mail)) {
//Toast exists
}
else {
//Toast not exists
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
In conclusion if I enter person1#m.de it should give out a toast that it exist
Here is a very easy way . Make your email as child . You have to replace the dot from the email and set it as child. (you can't use the email directly to a child)
static String encodeUserEmail(String userEmail) {
return userEmail.replace(".", ",");
}
static String decodeUserEmail(String userEmail) {
return userEmail.replace(",", ".");
}
Then you can easily match it like this :
final String input_mail = et_email.getText().toString();
DatabaseReference email = FirebaseDatabase.getInstance().getReference().child("email");
email.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(datasnapshot.child(input_mail).exits){
//Toast exists
}else {
//Toast not exists
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});

SingleValueEventListener do not get the value after button click

I need to get nickname value from Firebase Real time database after button is clicked. So i made singleValueListner() in button´s onClick method. But it don´t work.
I have tried debug it, but code didn´t get into singleValueEventListener()
Button getName = (Button)findViewById(R.id.getName);
getName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference db = FirebaseDatabase.getInstance().getReference().child("Member").child(user.getUid());
db.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
TextView tv = (TextView)findViewById(R.id.tv);
tv.setText(data.child("nickname").getValue().toString());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
Database JSON structure:
{
"Member" : {
"1Zuv6VZZ0kPluwc33f1QQQ7DZD93" /* UID */ : {
"-LgIHwiAjfuh5pjK7wzl" : {
"actualScore" : 0,
"bestScore" : 0,
"email" : "some#email.com",
"nickname" : "Vitek",
"season" : 0
}
}
}
}
Database structure:
https://drive.google.com/file/d/15B4b6Rb_WAiS6fioI9gItyijrbDiVjzJ/view
I need to get nickname, I think this is writen good, but not. So, what is wrong?
To get the value of your nickname property, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("Member").child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String nickname = dataSnapshot.child("nickname").getValue(String.class);
Log.d(TAG, nickname);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
The output in your logcat will be:
Vitek
So there is no need to loop through the DataSnapshot object in order to get the value of your nickname property. If you don't get this result, please check the logcat to see if you have an error message printed out.
You are only referring up to user's id but there is also a parent key of user detail which you need to reference.
tv.setText(data.child("LgiH------").child("nickname").getValue().toString());
but try to remove that second key from your registering user's code because it is not helpful.
You have made a mistake in refering your firebase root node. just change your line as below :
DatabaseReference db = FirebaseDatabase.getInstance().getReference("Member");
Now,just call your singlevalue event.
db.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
TextView tv = (TextView)findViewById(R.id.tv);
tv.setText(data.child("nickname").getValue().toString());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
This will do your stuff. try debugging your code with log at step by step.

Categories