使用警报对话框时从 Recycler View 中的 Firebase 删除项目

Delete Item from Firebase in Recycler View when using Alert Dialog Box

我使用 Firebase 数据库和存储将项目记录检索到回收站视图,并实施 public void onDeleteClick(int position) 以删除所选项目。并添加了一个自定义警告框以确认删除。只需单击删除即可在没有警报对话框的情况下正常工作。但是当我从对话框中选择“否”时,它无法再次删除并显示以下错误。

你能帮我解决这个问题吗?

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)

这是代码

@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();
                    }
                });
            }
        });
    }

适配器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;
    }
}

问题是您从 Firebase 存储中删除文件 之前 您曾经显示要求用户确认的警告框。流量为:

  1. 用户点击了删除按钮。
  2. 您的 onDeleteClick 找到图像 URL 的文件。
  3. 您的 onDeleteClick 删除了文件。
  4. 您的 onDeleteClick 要求用户确认他们要删除文件。
  5. 如果用户说“是”,您的 onDeleteClick 从数据库中删除对该文件的引用。

从上面可以看出,您在代码中过早地删除了文件。如果用户在第 5 步中单击“否”,然后再次单击 删除 按钮,则错误来自第 2 步,因为文件已经消失。

解决方法是在删除文件之前请求确认:

@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();
            }
        });
    }
}