I wish to delete specific user with phone number X from my DB. And insted my code deletes all of them.
Here is my DB:
Code:
private static void deleteUser(final Context context, final String phoneNumber) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("users");
Query usersQuery = databaseReference.orderByChild("phone").equalTo(phoneNumber);
usersQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dataSnapshot.getRef().removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d(TAG, "Deleted");
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "onCancelled", databaseError.toException());
}
});
}
Maybe it is not clear with my comment, so I am putting this as an answer, the full code that should not be having the problem you're facing, should look something like this:
usersQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()) {
ds.getRef().removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d(TAG, "Deleted");
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "onCancelled", databaseError.toException());
}
});
That's because you're using a singleValueEventListener. If the query matches multiple children, it returns a list of all those children.
Even if there's only a single matches child, it's still a list of one. And since you're calling getRef() on that list, you get the key of the location where you ran the query.
Related
Why data in the firebase are created this way and not in the normal way
this is my code
ProductRef.child(IdMesa_1).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
facturas.setValue(dataSnapshot.getValue().toString()).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task)
{
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
When you call dataSnapshot.getValue().toString(), you're converting a branch of your JSON tree into a string. When you then write that back to Firebase, it saves it as a string.
If you want to save it in the same structure as before, don't convert the data to a string. So:
ProductRef.child(IdMesa_1).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
facturas.setValue(dataSnapshot.getValue());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
I need to do join operation for data using the unique key provided by the Firebase database.Table habitat is created under the unique key of snake table.And also need to retrive data for list view or recyclerview.
databaseSnake = FirebaseDatabase.getInstance().getReference()
.child("snake")
.orderByKey()
.addValueEventListener(
new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
for (DataSnapshot child : dataSnapshot.getChildren())
{
// HERE CORRESPONDS TO JOIN
DatabaseReference Databasesnake = FirebaseDatabase.getInstance().getReference()
.child("habitat")
.orderByKey()
.addValueEventListener(
new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
// repeat!!
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
I have issues on nested queries I'm trying to do using firebase, seems like the first query (activity1) doesn't wait until the second (activity2) and third query (activity3) finished running, this might return NULL value from the first query. Please look at my sample for more understanding, I've been stuck here for days trying all kind of method but it just wont work. :(
Query query_1= reference.child("Users").child("Room")
.child("Profile");
query_1.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//ACTIVITY 1
Query query_2 = reference.child("Users").child(Room)
.child("Receiver").child("id");
query_2.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//ACTIVITY 2
Query query_3 = reference.child("chatrooms").child("Room")
.child("Creator").child("id");
query_3.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//ACTIVITY 3
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Hello Everyone I am using firebase database in my app. I am able to add data to database. Now I want to implement search in my app, I have two option for search users,
1)Blood Group
2)User Area
I am able to get data as per blood group selection, but I don't know how can I fetch data with blood group and area. (Multiple Selection Filter)
Now if the user will select 'A+' as blood group from spinner and select Area 'ABC'
Then result would come as Users with 'A+' blood group and 'ABC' area.
search_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Default Selected"+sel_blood_group);
mFirebaseDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Your Logic here
for (DataSnapshot eventSnapshot : dataSnapshot.getChildren()) {
UserRegisterModel mModel = eventSnapshot.getValue(UserRegisterModel.class);
// Log.e("DATA" ,""+ mModel.getName());
}
Query chatRoomsQuery = mFirebaseDatabase.orderByChild("blood_group").equalTo(sel_blood_group);
chatRoomsQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// dataSnapshot is the "issue" node with all children with id 0
for (DataSnapshot issue : dataSnapshot.getChildren()) {
// do something with the individual "issues"
UserRegisterModel mModel = issue.getValue(UserRegisterModel.class);
Log.e("QUERY DATA" ,""+ mModel.getName());
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Log.e("DATA" ,""+ chatRoomsQuery.toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
Firebase RealTime Database does not support multiple where clauses. So try to query with one filter and then filter the next one programatically.
search_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Default Selected"+sel_blood_group);
System.out.println("Default Selected"+sel_area);
mFirebaseDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Your Logic here
for (DataSnapshot eventSnapshot : dataSnapshot.getChildren()) {
UserRegisterModel mModel = eventSnapshot.getValue(UserRegisterModel.class);
// Log.e("DATA" ,""+ mModel.getName());
}
Query chatRoomsQuery = mFirebaseDatabase.orderByChild("blood_group").equalTo(sel_blood_group);
chatRoomsQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// dataSnapshot is the "issue" node with all children with id 0
for (DataSnapshot issue : dataSnapshot.getChildren()) {
// do something with the individual "issues"
UserRegisterModel mModel = issue.getValue(UserRegisterModel.class);
if(mModel.getArea().equals(sel_area))
Log.e("QUERY DATA" ,""+ mModel.getName());
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Log.e("DATA" ,""+ chatRoomsQuery.toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});enter code here
You can make userName to be added only once using the following method. I have assumed that you are storing the user details in UserRegisterModel class. Please take care of the DatabaseReferences as I have used what you have mentioned and I am not aware of your Database structure.
Query chatRoomsQuery = mFirebaseDatabase.orderByChild("User_Name").equalTo(userRegisterModel.getUserName());
chatRoomsQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
Log.e("UserAlready Registered");
}
else
{
mFirebaseDatabase.push().setValue(userRegisterModel);;
Log.i("User added Successfully");
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I have not tested the code but I think it will work! :)
I load two datasets in the onCreate function of my activity:
protected void onCreate(Bundle savedInstanceState) {
....
mDatabase.child("users").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
currentUser = dataSnapshot.getValue(Users.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "error:", databaseError.toException());
}
});
mDatabase.child("events").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
...
event = dataSnapshot.getValue(Events.class);
if (event.getHost().equals(currentUser.getId()) {
....
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "error:", databaseError.toException());
}
});
String name = currentUser.getName();
....
}
So I need some data of the users dataset in the events dataset. Most of the time this works, but since they are called async, they are sometimes loaded in the wrong order. So events is loaded before users is loaded.
How can I fix this?
If you want to guarantee the order, you can nest the loading of the events into the callback for the user:
String name;
mDatabase.child("users").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
currentUser = dataSnapshot.getValue(Users.class);
name = currentUser.getName();
mDatabase.child("events").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
...
event = dataSnapshot.getValue(Events.class);
if (event.getHost().equals(currentUser.getId()) {
....
}
}
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "error:", databaseError.toException());
}
});
}
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "error:", databaseError.toException());
}
});
The nesting becomes a bit deep, but if you pull the loading of events into a separate (named) method, that'll typically get better again.