Android-Firebase数据库读取失败:getUser方法未触发onDataChange求助
兄弟,花两小时排查这种问题确实闹心!我之前也遇到过类似的情况,onDataChange死活不触发但写入正常,大概率是这几个地方出问题了,你挨个排查下:
1. 最常见的坑:数据库权限规则
写入正常不代表读取权限也到位了!Firebase的权限是读写分开控制的,比如你的规则可能只开了写入权限,读取被完全禁止了。
比如你现在的规则可能是这样的:
{ "rules": { ".read": false, ".write": "auth != null" } }
这种情况下,登录用户能写入,但所有人都读不了,自然onDataChange不会触发。
解决方法:
- 测试阶段可以临时把读取权限放开(上线前一定要改回来!):
{ "rules": { ".read": true, ".write": "auth != null" } }
- 正式环境要根据业务设置精准权限,比如用户只能读取自己的数据:
{ "rules": { "users": { "$uid": { ".read": "$uid === auth.uid", ".write": "$uid === auth.uid" } } } }
2. 数据库引用路径不匹配
检查你getUser方法里的DatabaseReference路径,和saveUser写入的路径是不是完全一致!比如saveUser写到了users/{userId},但getUser不小心写成了user/{userId}(少了个s),或者userId的大小写、格式和数据库里的实际数据不匹配。
你可以在getUser里加个Log打印路径:
DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("users").child(userId); Log.d("FirebasePath", "读取路径:" + userRef.toString());
然后去Firebase控制台对比这个路径和实际数据的路径是否一致。
3. 忘记重写onCancelled方法,错过错误信息
很多人只写了onDataChange,但忽略了onCancelled,其实如果读取被拒绝或者出了其他错误,会走这个方法,你可以在这里拿到错误原因:
@Override public void onCancelled(@NonNull DatabaseError error) { Log.e("FirebaseError", "读取失败:" + error.getMessage() + ",错误码:" + error.getCode()); }
加了这个之后,就能知道是不是权限被拒绝、路径不存在或者其他网络问题了。
4. 监听器添加方式错误
确认你在getUser里是调用的addListenerForSingleValueEvent或者addValueEventListener,如果误写成了addChildEventListener,那监听单个节点时不会触发onDataChange,而是触发onChildAdded等方法。
另外,检查代码里有没有不小心调用了FirebaseDatabase.getInstance().goOffline(),如果强制离线了,自然读不到数据。
5. 数据压根不存在?
虽然你说onDataChange从未被调用,但还是确认下Firebase控制台里有没有对应路径的数据。如果节点不存在,onDataChange还是会触发,只是dataSnapshot.exists()会返回false,但如果是权限问题导致连节点都访问不到,就不会触发。
先把这几点排查一遍,大概率能解决问题!
内容的提问来源于stack exchange,提问作者Jan Frait

