提问者:小点点

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


我使用Firebase数据库和存储将项目记录检索到回收器视图,并实现了public void onDeleteClick(int位置)来删除选定的项目。并添加了一个自定义警报框来确认删除。当刚刚单击删除时,没有Alert Dialog,它非常有效。但是当我从对话框中选择“否”时,它不能再次删除,并显示以下错误。

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

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

适配器类

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

共1个答案

匿名用户

问题是您在显示要求用户确认的警报框之前从Firebase存储中删除了文件。流程是:

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

从上面可以清楚地看出,您在代码中过早删除了文件。如果用户在步骤5中单击“否”,然后再次单击Delete按钮,则错误来自步骤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();
            }
        });
    }
}