在Firestore中,我有一个名为'exclusiveB'的子集合中的数据,这个集合的文档的字段是'creditCard',它接受布尔值。
在上面提到的同一个Firestore中,我有另一个名为“exclusiveA”的子集合。
我写了一条安全规则,允许当前用户读取'exclusiveA'集合:如果当前用户具有uid,并且如果关于子集合'exclusiveB'中的当前用户的详细信息确认字段值'creditCard'为false。
收到的结果是Firestore拒绝了读取权限(尽管“creditCard”字段值为false)。有谁能解释一下原因,并提供一个解决方案?
请注意,父集合“users”、“userA”和“userB”除了确认持有子集合的文档的iD的单个值之外是空的,并且“exclusiveB”文档具有确认当前用户的uid的字段和确认文档的iD的另一个字段。
Firestore地层的照片如下:
安全规则包括:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users {
// if a rule isn't specified, Firestore denies by default
allow read;
}
match /users/{docId}/userA {
allow read;
}
match /users/{docId}/userB {
allow read;
}
match /users/{docId}/userA/{docId2}/exclusiveA/{docId3} {
// allow read if user: (1) has a uid, (2) has creditcard = false
allow get: if request.auth.uid != null && get(/databases/$(database)/documents/users/{docId}/userB/{docIdB}/exclusiveB/$(request.auth.uid)).data.creditCard == false;
}
match /users/{docId}/userB/{docId2}/exclusiveB/{xcluB} {
allow get: if resource.data.uid == request.auth.uid;
}
match /users/{docId}/userA/{docId2}/otherDetails/{id} {
allow read: if request.auth.uid == resource.data.id;
}
match /users/{docId}/userB/{docId2}/otherDetails/{id} {
allow read: if request.auth.uid == resource.data.id;
}
}
}
Firestore查询在用户界面级别的Flutter代码是:
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart' as auth;
import 'package:cloud_firestore/cloud_firestore.dart';
class StreamResults extends StatefulWidget {
@override
State<StreamResults> createState() => _StreamResultsState();
}
class _StreamResultsState extends State<StreamResults> {
final _auth = auth.FirebaseAuth.instance;
final _dB = FirebaseFirestore.instance;
final _dataSource = FirebaseFirestore.instance
.collection(
'users/l9NzQFjN4iB0JlJaY3AI/userA/2VzSHur3RllcF5PojT61/exclusiveA');
String? vehicleMake, vehicleTitle, currentUserID, pCurrency, currency, uid, docRefID;
int? maxSpeed, pullStrength;
void getIdentity() {
currentUserID = _auth.currentUser!.uid;
print('The current user\'s ID is: $currentUserID.');
}
Future<void> matchDetails() async {
final exclusiveBcollection = await _dB.collection('users/l9NzQFjN4iB0JlJaY3AI/userB/mv6YgmAfIDEkUNmstrzg/exclusiveB')
.where('uid', isEqualTo: currentUserID).get().then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
currency = doc['currency'];
uid = doc['uid'];
docRefID = doc['docRefID'];
});
});
}
@override
void initState() {
getIdentity();
matchDetails();
super.initState();
}
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _dataSource.where('preferredCurrency', isEqualTo: currency).snapshots().distinct(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
CircularProgressIndicator();
} else if (snapshot.hasData) {
final retrievedData = snapshot.data!.docs;
for (var specific in retrievedData) {
maxSpeed = specific['topSpeed'];
vehicleTitle = specific['vehicleName'];
pullStrength = specific['horsePower'];
vehicleMake = specific['vehicleBrand'];
pCurrency = specific['preferredCurrency'];
print('The vehicle\'s maximum speed = $maxSpeed.');
print('The vehicle\'s pulling strength = $pullStrength bph.');
print(
'The vehicle\'s brand is $vehicleMake, and its model-name is $vehicleTitle.');
print('The preferred currency = $pCurrency.');
}
}
return Column(
children: [
Text('The vehicle\'s maximum speed = $maxSpeed.'),
Text('The vehicle\'s pulling strength = $pullStrength bph.'),
Text(
'The vehicle\'s brand is $vehicleMake, and its model-name is $vehicleTitle.'),
],
);
});
}
}
谢谢
1条答案
按热度按时间tcomlyy61#
此查询:
这个查询:
从安全规则的Angular 来看,两者都试图将
list
文档化的子集合。但您的规则只允许单个文档get
操作:如果你想查询(
list
)一个集合,你需要添加这个权限。您可以通过指定list
或仅使用read
(get
和list
的组合)来实现这一点,如文档中所述。