joshmmo
joshmmo

Reputation: 1062

Subcollection resource variable in Firestore Rules

I have a tasks collection in firestore. Tasks have subcollections titled subtasks. Both tasks and subtasks have an owner field. I have the following Rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    function isSignedIn() {
      return request.auth != null;
    }

    match /tasks/{task} {
      allow read, update, delete: if isSignedIn() && request.auth.uid == resource.data.owner;
      allow create: if isSignedIn();
    
        match /subtasks/{subtask} {
            allow read, write: if isSignedIn() && request.auth.uid == resource.data.owner;
        }
    }
  }
}

The match /tasks/{task} works as expected with checking the auth uid against resource.data.owner. To avoid an extra get() charge I am storing the owner on the subtasks as well.

Why does request.auth.uid == resource.data.owner throw FirebaseError: Missing or insufficient permissions. when attempting to retrieve a subtask?

Edit: It also might be of important to reference how I am querying documents:

const subtasksSnapshot = await getDocs(collection(db, "tasks/" + taskId + "/subtasks"));
                
subtasksSnapshot.forEach((subtask) => {
    console.log(subtask.data());
});

Upvotes: 0

Views: 166

Answers (1)

Dharmaraj
Dharmaraj

Reputation: 50830

await getDocs(collection(db, "tasks/" + taskId + "/subtasks"));

When you run the above query, it also includes documents where owner is not current user. Security rules do not filter out data. You must filter out documents with given constraints yourself. Try running the following query:

const q = query(collection(db, "tasks/" + taskId + "/subtasks"), where("owner", "==", CURRENT_USER_ID))

const subtasksSnapshot = await getDocs(q);

Additionally, do ensure that user is logged in before running the query.

Upvotes: 1

Related Questions