0
votes

This is my Firestore directory structure:

items \ {document} \ 1 item with date, image etc
users \ {document} \ favoriteItems

On startup: the App downloads the list of items.

These are my old rules, which is obviously not correct for production:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

But with the old rules, I don't get the error. So it must be in the rules.

When the user favorite's an item for the first time, the user is not existent yet in the users collection. The users subdirectory have the document=** wildcard:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {    
    match /items/{document} {
      allow read, write: if request.auth.uid != null;
    }    
    match /users/{document=**} {
      allow read, write: if request.auth.uid == request.resource.data.author_uid
    }
  }
}

But these rules give below error:

Firestore: (21.4.2) [Firestore]: Listen for Query(target=Query(users/vsfcRpgewjNdFfQomf7MohcOMcA3/favoriteItems order by name);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}

That seems obvious because the first time the document does not exist yet. But also when it's present, I get the same error message. What are the proper rules for this?

1

1 Answers

0
votes

You're trying to read from collection users/vsfcRpgewjNdFfQomf7MohcOMcA3/favoriteItems, but only have rules defined for users/vsfcRpgewjNdFfQomf7MohcOMcA3. Since you're not granting recursive access in those rules, access to nested collections is denied.

You'll want to either allow nested access with a recursive wildcard:

match /users/{document=**} {
  allow read, write: if request.auth.uid == request.resource.data.author_uid
}

Or alternatively, allow access to the specific subcollection:

match /users/{document} {
  allow read, write: if request.auth.uid == request.resource.data.author_uid
  match /favoriteItems/{favorite} {
      allow read, write: if request.auth.uid == request.resource.data.author_uid
  }
}

The latter is more useful if your rules for the nested collections are different from the permissions on the containing document.