特定TLDR:规则".read": "auth != null && data.child('userEmail').val() === root.child('users').child(auth.uid).child('email').val()"
应在应用程序中按预期工作。
我已经按照文档进行操作,并且在规则规则下进行了测试,因此我认为这与我进行身份验证的方式有关吗?我将在下面提供信息,希望有人能尽快回答。
实时数据库结构:
"db-name": {
"units": {
0: {
"serial": "002",
"userEmail": "s@gmail.com"
},
1: {
"serial": "001",
"userEmail": "r@gmail.com"
}
},
"users": {
"R6nlZ...": {
"email": "r@gmail.com"
},
"qwerty...": {
"email": "s@gmail.com"
}
}
}
规则对象:
{
"rules": {
// ".read": "now < 1604037600000", // 2020-10-30
// ".write": "now < 1604037600000", // 2020-10-30
"units": {
".indexOn": "userEmail",
"$key": {
".read": "auth != null && data.child('userEmail').val() === root.child('users').child(auth.uid).child('email').val()",
".write" : "auth != null && data.child('userEmail').val() === root.child('users').child(auth.uid).child('email').val()"
}
},
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
规则测试: 模拟类型:读取 位置:https:db-name.firebaseio.com/units/1 阿姨:是的 提供者:匿名 UID:R6nlZ ... 结果:允许模拟读取
如果我尝试获取/units/0
,我会被拒绝,这是我的期望,因为这是当前授权用户无权查看的unit
。
现在,如果我使用普通的javascript进行操作,则不会获得与Firebase控制台中的“规则游乐场”相同的结果。
<!-- Add the entire Firebase JavaScript SDK -->
<script src="https://www.gstatic.com/firebasejs/7.24.0/firebase.js"></script>
<script>
// import * as firebase from "firebase";
var firebaseConfig = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "..."
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
var email = 'r@gmail.com';
var password = '123456';
// Sign in existing user
firebase.auth().signInWithEmailAndPassword(email, password).then(function() {
console.log('Signed in as: ' + firebase.auth().currentUser.email);
var dbUnits = firebase.database().ref().child('units').orderByChild('userEmail').equalTo(firebase.auth().currentUser.email);
var getUnitsDetails = function() {
return dbUnits.once('value').then(function(snapshot) {
snapshot.val() ?
Object.entries(snapshot.val()).map((unit) => {
return (
console.log('Serial number of unit: ' + unit[1].serial + ' & Owner of unit: ' + unit[1].userEmail)
)
})
:
console.log('no units found for that user bro')
})
}
console.log(getUnitsDetails());
}).catch(function(error) {
console.log(error);
});
当我按照粘贴的规则设置了Firebase权限时,用户r@gmail.com
看不到任何单位。如果我让读取权限完全打开(不是我想要的),则该用户可以看到其单位。
对我来说这没有意义,因为我认为auth.uid
是Firebase在用户登录时可以看到的内容,无论他们使用哪种登录类型。
答案 0 :(得分:1)
您的规则不允许此查询:
firebase.database().ref().child('units').orderByChild('userEmail').equalTo(firebase.auth().currentUser.email);
为使此查询正常工作,用户需要具有对/units
的读取权限。由于您没有在.read
上声明任何/units
规则,因此查询被拒绝。
您似乎认为规则将过滤数据以仅返回用户应有权访问的数据,但事实并非如此。如Firebase文档所述:rules are not filters。
但是security rules can be used on combination with queries是为了安全地允许查询数据。
在您的情况下,看起来像这样:
{
"rules": {
"units": {
".read": "auth.uid != null &&
query.orderByChild == 'userEmail' &&
query.equalTo == auth.token.email"
...
现在将允许您的查询,而其他/更广泛的/users
读操作将被拒绝。
答案 1 :(得分:0)
"$key": {
".read": "auth !== null && root.child('users').hasChild(auth.uid)",
".write" : "auth !== null && root.child('users').hasChild(auth.uid)"
}
这样写,用户集中存在的任何用户都可以访问“单位”
或者,您可以使用该用户的uid进行收集,并将密钥与他的uid匹配以进行访问