使用警报对话框时在回收站视图中从 Firebase 中删除项目

Posted

技术标签:

【中文标题】使用警报对话框时在回收站视图中从 Firebase 中删除项目【英文标题】:Delete Item from Firebase in Recycler View when using Alert Dialog Box 【发布时间】:2021-11-14 04:45:53 【问题描述】:

我使用 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();
                    
                );
            
        );
    

适配器类

 @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 存储中删除了文件您曾经显示要求用户确认的警报框。流程是:

    用户点击删除按钮。 您的onDeleteClick 找到了图片网址的文件。 您的onDeleteClick 删除了该文件。 您的onDeleteClick 要求用户确认他们要删除该文件。 如果用户说“是”,您的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();
            
        );
    

【讨论】:

我明白了。非常感谢您解释问题和解决方案。它现在正在工作。

以上是关于使用警报对话框时在回收站视图中从 Firebase 中删除项目的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 模拟器中从 firebase 推送通知

如何根据 Firebase Auth 错误消息在 Flutter 中显示自定义警报对话框?

使用 firebase 未显示回收站视图 - kotlin

在 400 HTTP 响应时在警报视图上显示 API 响应 JSON 格式的错误结果

使用 OnClick 删除回收站视图中的项目。 Firebase 安卓

Firestore如何在回收站视图中从firestore检索数据