Reputation: 88
I am working on an app for education that gives teachers access to student assignment documents based on a common subject. I have set a custom claim client-side for the teacher and set documents with a common field, "subject". My rule looks like this:
match /assignments/{entry} {
allow read: if isSignedIn() && resource.data.subject == request.auth.token.subject;
allow write: if request.auth.token.moderator == true;
//TODO: assignment rules go here
function isSignedIn() {
return request.auth.uid != null;
}
}
}
Despite everything I cannot get the resource to pull any data. Even
resource.data != null
displays false.
My custom claims come through fine and request.auth.token.subject == "Biology"
displays true for my example account.
Here is the query:
_guestBookSubscription = FirebaseFirestore.instance
.collection('assignments')
.orderBy('start_date', descending: true)
.limit(30)
.snapshots()
.listen((snapshot) {
_guestBookMessages = [];
for (final document in snapshot.docs) {
_guestBookMessages.add(RTIAssignment(
// endDate: (document.data()['end_date'] as DateTime),
standard: document.data()['standard'] as String,
startDate: DateTime.now(), // (document.data()['start_date']),
student: Student(name: document.data()['student_name']),
subject: document.data()['subject'] as String,
teacher: document.data()['name'] as String,
));
}
notifyListeners();
});
It's from the nifty codelabs on writing queries that Google puts out.
I'm not sure how to copy in the target document for the query. It's in Firebase and one of the fields is "subject".
Upvotes: 1
Views: 499
Reputation: 4603
Firestore rules are not for sorting data you can download and cannot download. You probably query data with no where()
method/function included. Firestore thinks you want to query all documents so he reject whole query.
Include in your query:
JavaScript
const q = query(citiesRef, where("subject", "==", "Biology"));
...
or
db.collection("cities").whereField("subject", isEqualTo: "Biology")
Probobly second .whereField()
method will work with flutter but i don't know.
This is how rules should looks like:
match /databases/{database}/documents {
match /{document=**} { // here you restrict access to whole database
allow read, write: if false;
}
match /assignments/{docID} { // here except data to whole database was restricted you allow to read write documents in this collection path.
allow read: if isTeacher() || isModerator()
allow write: if isModerator()
}
function isTeacher() {
return request.auth.token.subject == resource.data.subject
}
function isModerator() {
return request.auth.token.moderator == true;
}
}
Teachers with token.subject == "Biology"
can only request documents with field subject == "Biology"
so they need to use whereField()
in query. If teacher subject is "Math" he need to request only documents whereField("subject", isEqualTo: "Math")
Moderators no need to use "whereField()" they can read whole data.
Upvotes: 1