Firebase Realtime Database规则配置导致部分安卓设备用户注册异常求助
问题成因
- 异步操作时序错误:
setValue()是Firebase Realtime Database的异步网络请求,你在调用写入接口后未监听执行结果,直接执行了登出操作。不同设备的性能、网络环境存在差异,一加设备的写入请求在登出前就完成了安全规则校验,所以写入成功;三星设备的写入请求在登出后才触发规则校验,此时auth已变为null,触发.write: "auth != null"的校验逻辑,写入被拦截,导致用户记录创建失败,进而登录时读权限校验不通过无法登录。 - 安全规则配置不合理:当前规则为全局配置,只要登录就可以读写全库数据,权限粒度过大,存在数据泄露、篡改的安全风险,也不符合最小权限原则。
修复方案
1. 修正异步逻辑顺序
给setValue()添加完成监听,只有确认用户数据写入成功后,再执行跳转、登出操作,修改后的代码示例如下:
fAuth.createUserWithEmailAndPassword(reg_email, reg_password).addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { fAuth.getCurrentUser().sendEmailVerification().addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { userID = fAuth.getCurrentUser().getUid(); reg_user = new User(reg_email, sex, btn_text, 0, 0); // 增加写入完成监听 databaseReference.child(userID).setValue(reg_user) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> writeTask) { if(writeTask.isSuccessful()){ // 写入成功后再跳转、登出 Intent intent = new Intent(getApplicationContext(), LoginActivity.class); startActivity(intent); finish(); FirebaseAuth.getInstance().signOut(); }else{ // 写入失败给出提示,避免无感知失败 Toast.makeText(RegisterActivity.this, "用户信息创建失败:" + writeTask.getException().getMessage(), Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.INVISIBLE); } } }); } else { Toast.makeText(RegisterActivity.this, "Error " + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.INVISIBLE); } } }); } else { Toast.makeText(RegisterActivity.this, "Error " + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.INVISIBLE); } } });
2. 优化安全规则
将全局权限改为路径级权限,限制用户只能读写自己的用户节点,符合最小权限原则,规则配置如下:
{ "rules": { "Users": { "$uid": { ".read": "$uid === auth.uid", ".write": "$uid === auth.uid" } } } }
上述规则会校验当前登录用户的uid和要访问的节点uid是否一致,避免越权访问其他用户数据。
内容的提问来源于stack exchange,提问作者Hearent
相关产品推荐
相关产品推荐

