Remove value from Firebase Database issue (Android) - android

everyone! I want to delete the value from Firebase Database using RecyclerView.
However, I cannot find the key of a child, which I want to delete.
Firstly, I add data to the database like this:
String key = MainActivity.databaseReference.push().getKey();
MainActivity.databaseReference.child(key).setValue(myAppModel);
In terms of deleting, in my RecyclerView adapter i have written onClickListener to ImageView and delete item from list successfully!
In addition, i tried many ways of how to delete this item from database as well, but the data still untouched.
Here is the code:
holder.appDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mAppModelList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mAppModelList.size());
final ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
dataSnapshot.getValue(AppModel.class);
MainActivity.databaseReference.child(mAuth.getUid()).child(dataSnapshot.getRef().getKey()).removeValue();
System.out.println(dataSnapshot.getRef().getKey()); // it gives me user id...but in my MainActivity it gives the real key
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
MainActivity.databaseReference.addListenerForSingleValueEvent(eventListener);
}
});
As i mentioned in code comment, getRef().getKey() gives me the Firebase user id, like mAuth.getUid()
And in MainActivity i receive the real name(key) of child
Query query = databaseReference;
query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
AppModel appModel = dataSnapshot.getValue(AppModel.class);
appModelResult.add(0, appModel);
AddAppDialog.setAppModelResult(appModelResult);
System.out.println(dataSnapshot.getRef().getKey());
reloadFragment(fragment);
}
What i should do to delete the data from database?
Thanks everyone in advance!

Solved it!
Initially, when I want to delete item I wrote
MainActivity.databaseReference.child(mAuth.getUid()).child(appModel.getAppId()).removeValue();
However, as i noticed, you should not write user id
MainActivity.databaseReference.child(appModel.getAppId()).removeValue();
And here we are!
Hope, it could help everyone

Related

How can i get firebase child key value when i click on recyclerview item which is pushed to firebase

When using datasnapshot it deletes all messages but I want to delete the selected message only, so when I click on recyclerview item which is a message, delete that message from recyclerview as well as from firebase
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
final DatabaseReference freezerItemsRef = rootRef.child("messages");
freezerItemsRef.child(freezerItemsRef.getKey()).removeValue();
}
});
final DatabaseReference deleteChatRef = FirebaseDatabase.getInstance().getReference(Common.CHATS);
deleteChatRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
if (Objects.requireNonNull(snapshot.getRef().getKey()).equals(chatRef.get(position))) {
deleteChatRef.child(chatRef.get(position)).removeValue();
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
write this query in on clicklistener of your recycler view just write the path of your database chat node correctly instead of Common.Chat
To delete a specific message, you'll need to know the key of that message. In Firebase Realtime Database, such keys typically start with -L.... So say the user clicked the message with key -Lasdasd19191, you can delete the message with:
freezerItemsRef.child("-Lasdasd19191").removeValue();
To know the key of the message that the user clicked on, you'll typically need to map back from the index/position (which is what Android uses) in the list view that the user clicked on, to the key in the database (which is what Firebase needs). See my longer explanation of that here: Deleting row from recycler view and firebase

How to retrieve a List from Firebase avoid asynchronous

I know that when we retrieve data from Firebase ,it will be asynchronous, so ussally i will put all the code inside addChildEventListener, like example i want to sort userList below. But i am confused, if the List is really big, like million Users, so it means the method sortUser(user) will be called million times ? Can anyone explain this to me, I'm new to firebase
myRef.child("User").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
User user= dataSnapshot.getValue(User.class);
userList.add(user);
sortUser(userList);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You currently use a ChildEventListener, which means your onChildAdded gets called for each child node immediately and then later whenever a new child is added. This indeed can be a lot of invocations.
If you use a ValueEventListener, its onDataChange will only be called once for the initial data (no matter how many child nodes there are), and then once for each change.
By adding a ValueEventListener to your current set up, you can keep things simple: add the child nodes to the lit like you're already doing, but only sort in onDataChange.
myRef.child("User").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
sortUser(userList);
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
};
Firebase will only synchronize the data for the User node once, even when you have two listeners on it.
You should probably retrieve the data sorted server side by using order-by methods and then listen to that one.
var userRef = firebase.database().ref('posts').orderByChild('Users');
If I guess correctly, you would not need separate sorting client side.
You can also filter data. Do refer the docs

I'm trying to enter multiple values from an android activity to firebase Realtime database,but the button in the code dont work

I have already written code for inserting values into database.
button name is advbtn
Button does not respond to click.How to make it work?
public void Advbtn(View view) //code for button
{
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
getvalues();
ref.child("user").setValue(advposts);
Toast.makeText(Advpost.this,"Posted successfully",Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
});
}
}
I have also declared classes for making a table in the database and called it in this program.
you have to use
yourbutton.setonClickListner(New OnClickLisnter) method
your method mainly use for starting a new activity..

Unable to retrieve data from Firebase Realtime Database

I'm trying to display the "loc" of a part if its part number I given.
Here is what the data structure looks like:
{
"parts":{
"14521845": { "name":"TOOL EC160B/EC180B/EC210B/EC240", "loc":"EXC1", "sloc":"B3EGU01C03"},
"12829050": { "name":"SWITCH; IGNITION SWITCH", "loc":"PS01", "sloc":"85-06-013"},
"12829050": { "name":"SWITCH; IGNITION SWITCH", "loc":"COM1", "sloc":"B3RGK03D06"},
"20044893": { "name":"PARTS CATALOG_ENG_SPA_FRE_GER_KOR_EC210D", "loc":"EXC1", "sloc":"B3EGT01B02"}
}
}
Activity Code:
FirebaseDatabase firebaseDatabase=FirebaseDatabase.getInstance();
DatabaseReference databaseReference =firebaseDatabase.getReference("parts/"+curP);
databaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Products data=dataSnapshot.getValue(Products.class);
Log.i("",String.valueOf(data.getLoc()));
}
getLoc is the getter function for the Product class, and it returns the corresponding "loc" for the given curP. curP denoted the child values in parts.
The logic seems right to me, but I am not getting an output. Where am I going wrong here?
try this
getReference("parts").child(curP).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Products data = dataSnapshot.getValue(Products.class);
Log.i("", String.valueOf(data.getLoc()));
}
});
The problem is that what you are getting in onChildAdded() is not a whole Product object as you expect it to be.
In your database reference you are targeting a specific Product ("parts/"+curP) but using a ChildEventListener. The children of a specific product node are name, loc and sloc, so the onChildAdded() will trigger several times, giving you each of these properties as a dataSnapshot separately.
The two patterns you might use to get whole Product objects are either:
add a ChildEventListener directly to the "parts" node and you will get each of the Products as a child of that node, or;
if you are adding a listener directly to the node of a particular product, use a ValueEventListener, to get the whole of that nodes entry as one dataSnapshot.
You can try to use ValueEventListener. If you want read data once so use the addListenerForSingleValueEvent method, something like this:
private void getFirebaseLocValue(int curP) {
FirebaseDatabase firebase = FirebaseDatabase.getInstance();
DatabaseReference mDatabase = firebase.getReference("parts");
mDatabase.child(Integer.toString(curP))
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChildren()) {
Products data = dataSnapshot.getValue(Products.class);
Log.e("TAG", data.getLoc());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Or you can use addValueEventListener and will get data with any changes. I really don't think that ChildEventListener is a good idea to retrieve data from Firebase.

How to modify an specific value in Firebase?

I have this data in Firebase Database:
Negocios:
-KjfCu56lFZCybYldBZy
lugarReference: "Restaurante"
numeroMesas:39
password:"pass123"
user:"user123"
user_id:"usr_1"
I have two applications connected to one project in Firebase, one of them upload data of restaurants reservation, and the other one displays reservations in a RecyclerView.
In the first application, once I do a reservation, it must minus one to numeroMesas value, the other application should display any changes to this key.
In the reservation application, I have this piece of code that I did base in this question:
Update specific keys using Firebase for Android
It supposes to modify the value of numeroMesas, but it does not:
mReference.child("Negocios").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot : dataSnapshot.getChildren()){
Lugar lugar = postSnapshot.getValue(Lugar.class);
if(nombre_lugar.equals(lugar.getUser_id())){
DatabaseReference numMesasReference = mReference.child(dataSnapshot.getKey()).child("numeroMesas");
numMesasReference.setValue(lugar.getNumeroMesas() - 1);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
What it does is the next thing:
Negocios:
-KjfCu56lFZCybYldBZy
lugarReference: "Restaurante"
numeroMesas:39
password:"pass123"
user:"user123"
user_id:"usr_1"
-Negocios
-KjfCu56lFZCybYldBZy
numeroMesas:39
How can be fixed?
I need to minus one once I do a reservation...
Greetings!
Using postSnapshot.getRef() you obtain a reference to the source location for this snapshot. So what's next is to add a child to that reference, that reference will be "numeroMesas" that is the key you want to modify.
As easy as that, the code will be like this.
mReference.child("Negocios").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot : dataSnapshot.getChildren()){
Lugar lugar = postSnapshot.getValue(Lugar.class);
if(nombre_lugar.equals(lugar.getUser_id())){
DatabaseReference numMesasReference = postSnapshot.getRef().child("numeroMesas");
numMesasReference.setValue(lugar.getNumeroMesas() - 1);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
P.S: If you want to minus one just once by reservation, addValueEventListener() won't work, it will minus multiple time as a loop. Use addListenerForSingleValueEvent() instead addValueEventListener().
As the name says, this listener fits for single changes in the data at any location.
I guess the problem is with dataSnapshot.getKey() in this line
DatabaseReference numMesasReference = mReference.child(dataSnapshot.getKey()).child("numeroMesas");
Here you getting the key for the whole list of Negocios, not for the specific child replace it with `
postSnapshot.getKey()
The problem is that your DatabaseReference that you are using is wrong. You are missing a child. So in order to solve this problem, please use the following code:
mReference.child("Negocios").child(negociosId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int numeroMesas = (int) dataSnapshot.child("numeroMesas").getValue();
if(nombre_lugar.equals(lugar.getUser_id())){
mReference.child("Negocios").child(negociosId).child("numeroMesas").setValue(numeroMesas - 1);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
In which negociosId is the unique id generated by the push() method.
Hope it helps.
I'm new to firebase and android. But If the above solutions doesn't work please do the following. I think the problem is that you didn't convert the value of numeroMesas to string. Sorry if there's anything wrong.
Hope it helps.
mReference.child("Negocios").child(negociosId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(nombre_lugar.equals(lugar.getUser_id())){
mReference.child("Negocios").child(negociosId).child("numeroMesas").setValue((Integer.parseInt(dataSnapshot.child("numeroMesas").getValue().toString())) - 1);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});

Categories

Resources