问题
I just started using firebase and I'm amazed of how simple are complex things, and how complex simple things can be.
I need to check if a user exists in my Firebase database, and if exists, I need to get its key and value.
I have the key and I try to find it in the DB by going to my user subtree and loking for a child with the same key (ID)
DatabaseReference root_firebase = FirebaseDatabase.getInstance().getReference();
DatabaseReference users_firebase = root_firebase.child("Users");
DatabaseReference friend_found = users_firebase.child(key_searched_friend);
once I have it I try to call some method like
friend_found.getValue();
or
friend_found.child("user_name").getValue();
But it does not exist,
this seems weird since I can do both
friend_found.getKey();
friend_found.child("user_name").getKey();
I can't do this with the overriden method onDataChanged() since the data does not change when I query for this value.
This is my firebase database structure:
{
"RoomNames" : {
"Room-KM5cof0jcoMN8a4g6vC" : {
"room_name" : "TESTrOOM"
},
"Room-KM5dg_WPRdEOT4_oJ1r" : {
"room_name" : "testRoom2"
}
},
"Users" : {
"User-KM5ZaGq0xvjQis05CPF" : {
"user_name" : "Enrique"
}
}
}
回答1:
You say: I can't do this with the overriden method onDataChanged() since the data does not change when I query for this value
The guide for how to Retrieve Data explains that:
Firebase data is retrieved by attaching an asynchronous listener to a FirebaseDatabase reference. The listener is triggered once for the initial state of the data and again anytime the data changes.
So when you attach a listener to a location, onDataChanged() fires and gives you the current value.
In the section titled Read Data Once, the guide states:
In some cases you may want a callback to be called once and then immediately removed, such as when initializing a UI element that you don't expect to change. You can use the addListenerForSingleValueEvent() method to simplify this scenario: it triggers once and then does not trigger again.
回答2:
Use as below :
friend_found.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.e(TAG,"Error while reading data");
}
});
回答3:
For a database reference object, the same way one can add an event listener, it can also be removed, using removeEventListener
.
Instead of creating an anonymous object like this
friend_found.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.e(TAG,"Error while reading data");
}
});
you can create a named object of ValueEventListener
and remove it from the database reference object using removeEventListener
, at the end of the onDataChange
method
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
friend_found.removeEventListener(valueEventListener);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.e(TAG,"Error while reading data");
}
});
friend_found.addValueEventListener(valueEventListener);
The code inside onDataChange
method gets executed only once as the ValueEventListener
object is removed as soon as the last line of the method gets executed.
来源:https://stackoverflow.com/questions/38255513/how-to-get-a-value-once-of-a-firebase-database-android