I retrieved item records to the recycler view using the Firebase database and storage and implemented public void onDeleteClick(int position)
to delete the selected item. And added a custom alert box to confirm the deletion. It is pretty working without Alert Dialog when just clicked delete. But when I choose "No" from Dialog It cannot be deleted again and shows the following error.
Can you help me to solve this issue.
E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
E/StorageException: { "error": { "code": 404, "message": "Not Found. Could not delete object", "status": "DELETE_OBJECT" }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found. Could not delete object", "status": "DELETE_OBJECT" }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:445)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:462)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:453)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
Here is the code
@Override
public void onDeleteClick(int position) {
Upload selectedItem = mUploads.get(position);
StorageReference imageRef = mStorage.getReferenceFromUrl(selectedItem.getmImageUrl());
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
View view = LayoutInflater.from(ShowPatientsRecords.this).inflate(R.layout.alertdelete, null);
Button no = view.findViewById(R.id.dltNo);
Button yes = view.findViewById(R.id.dltYes);
AlertDialog dialog = new AlertDialog.Builder(ShowPatientsRecords.this).setView(view).create();
dialog.setCancelable(false);
dialog.show();
yes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Upload selectedItem = mUploads.get(position);
final String selectedKey = selectedItem.getmKey();
mDatabaseRef.child(selectedKey).removeValue(); **//This line is not working after No click in the Alert Dialog**
dialog.dismiss();
Toast.makeText(ShowPatientsRecords.this, "Record deleted", Toast.LENGTH_LONG).show();
}
});
no.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
});
}
Adapter Class
@Override
public int getItemCount() {
return mUploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnCreateContextMenuListener,
MenuItem.OnMenuItemClickListener{
public TextView recDate;
public TextView recDes;
public TextView recDoc;
public ImageView imageView;
public ImageViewHolder(@NonNull View itemView) {
super(itemView);
recDate = itemView.findViewById(R.id.showdate);
recDes = itemView.findViewById(R.id.showdescription);
recDoc = itemView.findViewById(R.id.showdoc);
imageView = itemView.findViewById(R.id.showImage);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}
@Override
public void onClick(View v) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Select Action");
MenuItem delete = menu.add(Menu.NONE, 1, 1, "Delete");
delete.setOnMenuItemClickListener(this);
}
@Override
public boolean onMenuItemClick(MenuItem item) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
switch (item.getItemId()) {
case 1:
mListener.onDeleteClick(position);
return true;
}
}
}
return false;
}
}
public interface OnItemClickListener {
void onItemClick(int position);
void onDeleteClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
mListener = listener;
}
}
The problem is that you delete the file from Firebase Storage before you ever show the alert box that asks the user to confirm. The flow is:
onDeleteClick
finds the file for the image URL.onDeleteClick
deletes the file.onDeleteClick
asks the user to confirm they want to delete the file.onDeleteClick
delete the reference to the file from the database.From the above it's clear that you delete the file too early in your code. If the user clicks "No" in step 5, and clicks the Delete button again, the error comes from step 2 as the file is already gone.
The solution is to ask for confirmation before deleting the file:
@Override
public void onDeleteClick(int position) {
Upload selectedItem = mUploads.get(position);
StorageReference imageRef = mStorage.getReferenceFromUrl(selectedItem.getmImageUrl());
View view = LayoutInflater.from(ShowPatientsRecords.this).inflate(R.layout.alertdelete, null);
Button no = view.findViewById(R.id.dltNo);
Button yes = view.findViewById(R.id.dltYes);
AlertDialog dialog = new AlertDialog.Builder(ShowPatientsRecords.this).setView(view).create();
dialog.setCancelable(false);
dialog.show();
yes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Upload selectedItem = mUploads.get(position);
final String selectedKey = selectedItem.getmKey();
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
mDatabaseRef.child(selectedKey).removeValue();
dialog.dismiss();
Toast.makeText(ShowPatientsRecords.this, "Record deleted", Toast.LENGTH_LONG).show();
}
});
}
});
no.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}
}