You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用addValueEventListener()时出现Firebase Database权限拒绝错误

Firebase数据加载问题:addValueEventListener无响应且权限被拒

问题场景

我正在使用Firebase获取数据并加载到包含列表的Fragment中,计划通过自定义适配器(接收三个ArrayList作为输入)来构建列表。目前代码能成功将Firebase中存储的dates键文本设置到按钮上,说明连接没有问题,但addValueEventListener的代码完全不生效——ArrayList没有添加数据,回调里的Toast消息也没显示,同时出现以下错误:

Listen at /Attendance/1/A/1 failed: DatabaseError: Permission denied

相关代码

AttendanceFragment 代码

public class AttendanceFragment extends Fragment { 
    private DatabaseReference reference, attendance, classid, divisionid, studentid, dates; 
    private Button attbutton; 
    private ListView list; 
    private View mainview; 
    private Activity activity; 
    private ArrayList<String> date = new ArrayList<String>(), state = new ArrayList<String>(), teacher = new ArrayList<String>(); 
    private ListAdapter listAdapter; 

    @Nullable 
    @Override 
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
        return inflater.inflate(R.layout.fragment_attendence,container,false); 
    } 

    @Override 
    public void onStart(){ 
        super.onStart(); 
        mainview = this.getView(); 
        activity = this.getActivity(); 
        attbutton = mainview.findViewById(R.id.att_per); 
        list = mainview.findViewById(R.id.att_main_list); 
        reference = FirebaseDatabase.getInstance().getReference(); 
        attendance = reference.child(KeyStrings.attendance); 
        classid = attendance.child(KeyStrings.class1); 
        divisionid = classid.child(KeyStrings.division1); 
        studentid = divisionid.child(KeyStrings.student1); 
        dates = studentid.child("2018-07-06"); 
        attbutton.setText(dates.getKey()); 

        studentid.addValueEventListener(new ValueEventListener() { 
            @Override 
            public void onDataChange(DataSnapshot dataSnapshot) { 
                Toast.makeText(activity, "Does it work?", Toast.LENGTH_LONG).show(); 
                for(DataSnapshot d1: dataSnapshot.getChildren()){ 
                    date.add(d1.getKey()); 
                    state.add(d1.child(KeyStrings.att_status).getValue().toString()); 
                    teacher.add(d1.child(KeyStrings.att_created_by).getValue().toString()); 
                } 
                listAdapter = new AttendanceAdapter(activity, date, state, teacher); 
                list.setAdapter(listAdapter); 
            } 

            @Override 
            public void onCancelled(DatabaseError databaseError) { } 
        }); 
    } 
}

AttendanceAdapter 代码

public class AttendanceAdapter extends ArrayAdapter<String>{ 
    private ArrayList<String> date; 
    private ArrayList<String> state; 
    private ArrayList<String> teacher; 
    private Activity context; 

    public AttendanceAdapter(Activity context, ArrayList<String>date, ArrayList<String>state, ArrayList<String>teacher) { 
        super(context, R.layout.fragment_attendence, date); 
        this.date=date; 
        this.state=state; 
        this.teacher=teacher; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent){ 
        LayoutInflater inflater = context.getLayoutInflater(); 
        View listviewItem = inflater.inflate(R.layout.fragment_attendence,null,true); 
        TextView dateview=(TextView)listviewItem.findViewById(R.id.att_list_date); 
        TextView stateview=(TextView)listviewItem.findViewById(R.id.att_list_stat); 
        TextView teacherview=(TextView)listviewItem.findViewById(R.id.att_list_teacher); 
        dateview.setText(date.get(position)); 
        stateview.setText(state.get(position)); 
        teacherview.setText(teacher.get(position)); 
        return listviewItem; 
    } 
}

补充信息(编辑1)

我原本以为是Firebase权限或认证问题,附上当前的实时数据库规则:

{ "rules": { ".read": true, ".write": true } }

问题分析与解决方案

嘿,我来帮你捋捋这个问题的关键点~

1. 先解决核心的权限拒绝问题

虽然你贴了全开放的规则,但还是出现Permission denied,可以从这几个方向排查:

  • 规则是否真的同步生效?:修改Firebase规则后,有时候需要等待1-2分钟才能全局同步,你可以试试重启模拟器/测试设备,或者在Firebase控制台重新发布一次规则。
  • 数据库路径是否匹配?:错误里的路径是/Attendance/1/A/1,你可以直接在Firebase实时数据库控制台手动访问这个路径,看看节点是否存在、拼写是否正确(比如大小写、节点名称有没有打错)。如果路径不存在,也可能触发权限错误。
  • 是否混淆了数据库服务?:确认你修改的是实时数据库的规则,而不是Firestore的——这两个是完全独立的服务,规则不通用。
  • 认证状态缓存问题:如果你的App启用了Firebase Auth,本地缓存的认证状态可能异常。可以在代码里打印当前用户状态排查:
    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    Log.d("AuthCheck", user == null ? "未登录" : "当前用户ID:" + user.getUid());
    
    要是未登录状态却读不到,试试清除App数据后重新测试。

2. 代码逻辑的优化点

就算权限问题解决了,你的代码还有几个小坑需要修正:

  • Fragment获取View的方式:建议在onCreateView里直接保存View实例,避免onStart时getView()返回null的情况:
    private View mainview;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mainview = inflater.inflate(R.layout.fragment_attendence,container,false);
        return mainview;
    }
    
  • 适配器布局错误:你在适配器的构造方法和getView里都用了fragment_attendence(Fragment的布局),这会导致列表项布局嵌套混乱。应该创建单独的列表项布局(比如attendance_list_item.xml),然后在适配器里引用这个布局。
  • 数据重复累加问题:addValueEventListener会在数据变化时重复触发,每次回调前要先清空三个ArrayList,不然数据会重复添加:
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Toast.makeText(activity, "Does it work?", Toast.LENGTH_LONG).show();
        // 先清空列表
        date.clear();
        state.clear();
        teacher.clear();
        for(DataSnapshot d1: dataSnapshot.getChildren()){
            date.add(d1.getKey());
            state.add(d1.child(KeyStrings.att_status).getValue().toString());
            teacher.add(d1.child(KeyStrings.att_created_by).getValue().toString());
        }
        // 不用重新创建适配器,直接通知数据变化即可
        if(listAdapter == null){
            listAdapter = new AttendanceAdapter(activity, date, state, teacher);
            list.setAdapter(listAdapter);
        } else {
            listAdapter.notifyDataSetChanged();
        }
    }
    

内容的提问来源于stack exchange,提问作者Mihir Tanksale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:04:26