Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore Database Rules and Structure for sharing Documents between users

I'm trying to create an application which allows users to collaborate on lists. Every user needs to be invited in order to be able to work on the list.

I structured my data like that (loosely based on this blog post). Also this structure can be changed if needed.

list
  list_1:
    users:
      owner:
        [email protected]: true
      shared:
        [email protected]: true
        [email protected]: true
    id
    name
    items:
      item_1:
        id:
        name:
      ...

What I'm trying to achieve: Everyone should be able to create lists. They creator then becomes the owner of the created list. Only the owner and users in the "shared" document should be able to read and write to this list.

I guess that the permission settings should look something like this. But this isn't working:

service cloud.firestore {
  match /databases/{database}/documents {
    match /lists/{listId}/{anything=**} {
        allow read, write: if !exists(resource.data.users.owner) ||
                               resource.data.users.owner == request.auth.token.email ||
                               request.auth.token.email in resource.data.users.shared
    }
  }
}
like image 646
Marcel Bochtler Avatar asked Oct 08 '17 13:10

Marcel Bochtler


People also ask

What file should be used for firestore rules firestore rules?

firestore. rules // is a file used to define the security rules for your Firestore database. firestore.

How to set rules for Firestore database?

To set up and deploy your first set of rules, open the Rules tab in the Cloud Firestore section of the Firebase console. Write your rules in the online editor, then click Publish.

Can two documents have the same ID in firestore?

New document with same ID should not be allowed in the same collection. It should be possible to fetch an already existing document from a previous import.


1 Answers

I was able to figure it out.

I changed the data structure to this:

list
  list_1
    owner: [email protected]
    writeAccess: [[email protected], [email protected]]
    id
    name
    items:
      item_1:
        id:
        name:
      ...

Then the database rules like this are working:

service cloud.firestore {
  match /databases/{database}/documents {
    match /lists/{listId} {
        // Allow RW on lists for owner, shared user or for everyone if it's a new list
      allow read, write: if resource.data.owner == request.auth.token.email ||
                            request.auth.token.email in resource.data.writeAccess ||
                            !exists(/databases/$(database)/documents/lists/$(listId))
    }
    match /lists/{listId}/items/{itemId} {
        // Allow RW on item for owner or shared user of parent list
        allow read, write: if get(/databases/$(database)/documents/lists/$(listId)).data.owner == request.auth.token.email ||
                              request.auth.token.email in get(/databases/$(database)/documents/lists/$(listId)).data.writeAccess ||
                             !exists(/databases/$(database)/documents/lists/$(listId)) // Needed for new lists. Because lists and items are created in a batch
    }
  }
}
like image 54
Marcel Bochtler Avatar answered Oct 24 '22 07:10

Marcel Bochtler