Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore rules, what is a collection and a document?

I mean I know what those are but I am a bit confuse about the security rules, for example:

service cloud.firestore {
  match /databases/{database}/documents {
    // This is probably a mistake
    match /spaceships { // <= what is this a collection or a document?
      allow read;
      // In spite of the above line, a user can't read any document within the 
      // spaceship collection.
    }
  }
}

Firebase documentation says:

Rules for collections don't apply to documents within that collection. It's unusual (and probably an error) to have a security rule that is written at the collection level instead of the document level.

That means that this match /spaceships {... is a collection right?

But later on we have this:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**}{ // <= what is this a document or a collection?
      allow read, write: if true;
    }
  }
}

I don't understand is this match /{document=**}{... a document? or a collection? I mean is at the collection level.

like image 950
Ahsath Avatar asked Mar 07 '23 20:03

Ahsath


2 Answers

Paths in Firestore are alternating collections and documents: /collection/document/subcollection/subdocument

For example:

// Matches kaylee, the mechanic on serenity
/spaceships/serenity/crew/kaylee/...

When using security rules, you can specify wildcards:

// This will match any spaceship, and any crewmember
/spaceships/{spaceshipId}/crew/{crewmemberId}/...

Now imagine that you have another subcollection under spaceships:

/spaceships/{spaceshipId}/stowaways/{stowawayId}/...

If you want to write rules against multiple subcollections, you need to either:

// You could use multiple single wildcards
/spaceships/{spaceshipId}/{crewOrStowaway}/{crewOrStowawayId}/...

// Or you could use a multi-segment wildcard
/spaceships/{spaceshipId}/{allShipInformation=**}

This returns allShipInformation as a path, which will match all documents and collections at and below that path. Note that it's one or more path segment, rather than zero or more.

You can read more about this in the docs

like image 83
Mike McDonald Avatar answered Mar 10 '23 11:03

Mike McDonald


In your first example /spaceships is at the collection level. As was stated in the quote you referenced, placing a rule here is not helpful as it won't be applied to any of the documents in the collection.

In your second example /{document=**} is at the collection level but is using a recursive wildcard. In short, what this does is apply the rule to the documents within this collection and to any documents within any subcollections of this collection.

This allows you to write:

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

Instead of:

service cloud.firestore {
  match /databases/{database}/documents {
    match /spaceships/{shipId} {
      allow read, write: if true;
    }
    match /spaceships/{shipId}/crew/{crewMemberId} {
      allow read, write: if true;
    }
  }
}
like image 30
Kyle Avatar answered Mar 10 '23 10:03

Kyle