Firebase RTDB分片权限规则模拟器有效但Web应用失效排查
解决Firebase分片数据库权限认证不生效的问题
嘿,我帮你定位到问题核心了——你的分片数据库App没有继承主App的认证状态,这就是为什么规则里的auth.uid拿不到有效值,导致写入被拒绝;而模拟器里能正常运行,是因为模拟器是手动指定了认证信息的。
问题根源
每个Firebase App实例都是独立的,当你初始化第二个App(分片的shardApp)时,它不会自动共享主App里已登录用户的会话。所以分片App此时处于未认证状态,规则中的auth对象为null,自然触发权限拒绝逻辑。
修复方案:手动传递认证凭证
你需要把主App中已登录用户的认证令牌传给分片数据库,代码修改如下:
async function init(){ try{ firebase.database.enableLogging(true); const defaultApp = firebase.initializeApp(config); const auth = defaultApp.auth(); const s = "alice@example.com"; await auth.signInWithEmailAndPassword(s,s); // 获取当前用户的有效认证令牌,强制刷新确保有效性 const user = auth.currentUser; const idToken = await user.getIdToken(true); // 初始化分片数据库App const shardApp = firebase.initializeApp({databaseURL:shard}, 'dbAppShard'); const db = firebase.database(shardApp); // 为分片数据库设置认证令牌,关联当前用户会话 db.authWithCustomToken(idToken); const uid = user.uid; const ref = db.ref(`/chat/${uid}/fail/${uid}`); const time = firebase.database.ServerValue.TIMESTAMP; ref.set({time}); } catch(e) { console.error("init failed",e); } }
关键细节说明
- 规则逻辑本身有效:你编写的权限规则在模拟器中正常运行,说明规则逻辑是正确的,只是实际运行时分片App未认证,导致
auth.uid为null,$pId== auth.uid条件不成立。 - 关于规则写法疑问:你提到的几种规则写法(
.write": true、auth.uid != null等)都是有效的,只是分片App未认证时auth.uid != null返回false,所以写入被拒。 - 令牌刷新的必要性:调用
getIdToken(true)强制刷新令牌,是为了避免使用过期的令牌,确保分片数据库的认证能成功完成。
验证方式
修改代码后重新运行Web应用,打开控制台查看日志,应该能看到分片数据库的认证状态变为已认证,写入操作也会成功执行。
内容的提问来源于stack exchange,提问作者Chris Chiasson
相关产品推荐
相关产品推荐

