rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /shoppinglist/{lists} { function isSignedIn() { return request.auth != null; } function isEmailVerified() { return request.auth.token.email_verified != false; } function isKnownUser() { return isSignedIn() && request.auth.uid != "" && isEmailVerified(); } function UserId() { return request.auth.uid; } function getOwner(rsc) { // Read Owner in the resource (rsc). return rsc.data.owner; } function getShares(rsc) { // Read Shares in the resource (rsc). return rsc.data.shares; } function isOwner(rsc) { // Determine if the user is the owner return isKnownUser() && (getOwner(rsc) == UserId()); } function isShared(rsc) { // Determine if the user was shared the list return isKnownUser() && (UserId() in getShares(rsc)); } function getParentDoc(){ // Get the parent document return get(/databases/$(database)/documents/shoppinglist/$(lists)); } allow read: if isOwner(resource) || isShared(resource); allow write: if isOwner(resource); match /items/{items} { allow read: if isOwner(getParentDoc()) || isShared(getParentDoc()); allow write: if isOwner(getParentDoc()); } } } }