Android Firebase database limitToLast(1) weird behaviour - java

I have a very simple code:
// get users poll date, and set in relevant text view
Query query = gameRef.child("users_loto").child("zaalkIb4W0V7MGbekLhqjP34IQi1").orderByChild("pollRank").limitToLast(1);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
nDate = Long.parseLong(ds.child("pollRank").getValue().toString().substring(0, 14));
user_result.setText(String.valueOf(nDate));
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
query.addListenerForSingleValueEvent(valueEventListener);
I ordered it by pollRank - it is the same number as the child name.
It seems to return the last value of the relevant node:
But instead, it always returns the one before :
A very weird behavior...
Any thoughts about why it happens?

Tnx for #ShehanWisumperuma!
gameRef.keepSynced(true) was the correct answer to my issue!!!
Tnx for all of you who tried to help me!

Related

Android studio - get collection from user in firebase using java

I'm trying to get the "bet" collection from the firebase database (on android studio, using java).
this is the collection
pic1
pic2
,I got User class that has the fields
"full_name","email","password".
what should i do with the "bet" collection?
I tried
reference = FirebaseDatabase.getInstance().getReference().child("Users");
db = FirebaseFirestore.getInstance();
db.collection("Users").document(UserID).get().addOnCompleteListener(task ->{
if(task.isSuccessful() && task.getResult() != null){
String number_bet = task.getResult().getString("bet");
}
} );
It failed and i couldn't find any solutions
,I can access the other fields, for example
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
User user1 = snapshot.getValue(User.class);
if(user1 != null){
user_submit.setText(user1.bet_display);
}
}
all that i need is to get the drawn number (0-36) value(in that case String)
thanks!
that worked for me.
DatabaseReference reference=FirebaseDatabase.getInstance().getReference().child("Users");
reference.child(UserID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String str2 = snapshot.child("bet").child(""+NUMBER).getValue().toString(); }
}
#Override
public void onCancelled(#NonNull DatabaseError error) { }
});
NUMBER is the path, it drawn every time..
just got to the right path by snapshot.child(some key).child(some key)....getValue().toString()

How to make two Firebase database calls one inside the other Java Android

I want to make two database calls one inside the other and make use of the first call data. Since firebase database calls are asynchronous this is not behaving the way I want.
I HAVE two database nodes Users, Chats.
I want first query through one Users at a time and take the user id and then query through the Chats model and check if the id in Users and Chats nodes are same
Something like this.
database.getReference().child("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
users = dataSnapshot.getValue(Users.class);
users.setUserId(dataSnapshot.getKey());
database.getReference().child("Chats").child(auth.getUid() + users.getUserId()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
//ADD USER TO LIST UPDATE UI
list.add(users);
}
else{
//DON'T ADD USER
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Hope I made the problem clear.

Firebase Realtime Databse DataSnapshot only Read the last value in the child

I'm calling addValueEventListener inside the button click, but this method only reads the last item in the node. I want to read all the child value in the node What went wrong here?
btnorder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1:dataSnapshot.getChildren())
{
SelectedItems si=dataSnapshot1.getValue(SelectedItems.class);
si.getItemname();
Toast.makeText(MyBookedItems.this, ""+si.getItemname(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
I think you can create an array list and put all snapshot data into it, and then you can find the last data of the list with the value you find by subtracting one from the length of the list. Sorry for my bad English :( I have tried to explain in the solution in the code below)
ArrayList<SelectedItems> selectedItems = new ArrayList<SelectedItems>();
for(DataSnapshot dataSnapshot1:dataSnapshot.getChildren())
{
SelectedItems si=dataSnapshot1.getValue(SelectedItems.class);
selectedItems.add(si);
}
selectedItems.get(selectedItems.size());
It's read all the values but I got the output as a Toast message, because of that I only see the last value)

Value of variable changes after applying the same method twice Firebase

I have a Firebase database that I want to retrieve the friend ID from. This works perfectly as I'm getting the right value when logging the friendUserId in the for loop. However, the log at the end of the method only displays the right value after executing the method twice. At first it displays "s", the second time it displays the string that I want. I feel like it has got something to do with processing time of the query, but I'm not sure really. How do I solve this?
public String friendUserId="s";
public void checkUserExistence() {
mDatabase.child("Users")
.orderByChild("username")
.equalTo(EmailSearchQuery)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
friendUserId = childSnapshot.getKey();
Log.d("dwada",friendUserId);
}
} else
Toast.makeText(AddAFriend.this, "Gebruiker niet gevonden", Toast.LENGTH_LONG);
}
#Override
public void onCancelled(DatabaseError firebaseError) {
Log.e("MainActivity", "onCancelled", firebaseError.toException());
}
});
Log.d("dwada",friendUserId);
}

how to stop value event listener from listening after a condition is met

for example searching in circles for a user circle if a data exist I want it DO process 1 and if data doesn't exist I want it to create one then DO process 2 ... but what happens in this code if data doesn't exist it will create one then do process 2 then go back then do process 1 after checking. so how can I stop the listener after process 2.
sorry if the circles example is too ambiguous but this is the simplest example I could think of .
Firebase ref= new Firebase("https://XXXXX.firebaseio.com/circles/");
Query queryRef = ref.orderByChild("circalename").equalTo(user.circalename);
ValueEventListener listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot datasnapshot) {
if (datasnapshot.exists()) { // I don't want to get back here after
//creating the data in the else statement
// DO process 1
}
// if my data doesnt exist I will create one after that STOP listening
else {
// create circle
// do process 2
}
}
What you can do is use addListenerForSingleValueEvent
as it listens to the event only once
i.e. in your case
queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
if (datasnapshot.exists()) {
// code if data exists
} else {
// code if data does not exists
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Despite Shubham Arora's answer is the best solution for this case, I'm going to show you how to do exactly what you asked with these two solutions that are quite simple:
1. Global boolean
Create a global boolean and change it once your condition is met:
query.addListenerForSingleValueEvent(new ValueEventListener() {
boolean processDone = false;
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists() && !processDone) {
// do process 1
} else {
// do process 2
processDone = true;
}
}
#Override public void onCancelled(DatabaseError databaseError) {}
});
2. Remove listener
Remove your listener once your condition is met:
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// do process 1
} else {
// do process 2
query.removeEventListener(this);
}
}
#Override public void onCancelled(DatabaseError databaseError) {}
});
Both solutions did work fine for me when I was using ChildEventListener and Shubham Arora's answer couldn't help.

Categories

Resources