Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Como estruturar regras de segurança do Cloud Firestore

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

As regras de segurança do Cloud Firestore permitem controlar o acesso a documentos e coleções em seu banco de dados. A sintaxe de regras flexíveis permite que você crie regras que correspondam a qualquer coisa, desde todas as gravações em todo o banco de dados até operações em um documento específico.

Este guia descreve a sintaxe básica e a estrutura das regras de segurança. Combine essa sintaxe com condições de regras de segurança para criar conjuntos de regras completos.

Declaração de serviço e banco de dados

As regras de segurança do Cloud Firestore sempre começam com a seguinte declaração:

service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}

A declaração do service cloud.firestore o escopo das regras para o Cloud Firestore, evitando conflitos entre as regras de segurança do Cloud Firestore e as regras de outros produtos, como o Cloud Storage.

A declaração match /databases/{database}/documents especifica que as regras devem corresponder a qualquer banco de dados do Cloud Firestore no projeto. Atualmente, cada projeto possui apenas um único banco de dados chamado (default) .

Regras básicas de leitura/gravação

As regras básicas consistem em uma declaração de match especificando um caminho de documento e uma expressão de allow detalhando quando a leitura dos dados especificados é permitida:

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

Todas as declarações de correspondência devem apontar para documentos, não para coleções. Uma declaração de correspondência pode apontar para um documento específico, como em match /cities/SF ou usar curingas para apontar para qualquer documento no caminho especificado, como em match /cities/{city} .

No exemplo acima, a instrução match usa a sintaxe curinga {city} . Isso significa que a regra se aplica a qualquer documento da coleção de cities , como /cities/SF ou /cities/NYC . Quando as expressões de allow na instrução de correspondência são avaliadas, a variável city resolverá o nome do documento da cidade, como SF ou NYC .

Operações granulares

Em algumas situações, é útil dividir a read e a write em operações mais granulares. Por exemplo, seu aplicativo pode querer impor condições diferentes na criação do documento e na exclusão do documento. Ou você pode permitir leituras de documentos únicos, mas negar consultas grandes.

Uma regra de read pode ser dividida em get e list , enquanto uma regra de write pode ser dividida em create , update e delete :

service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules
    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }

    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}

Dados hierárquicos

Os dados no Cloud Firestore são organizados em coleções de documentos, e cada documento pode estender a hierarquia por meio de subcoleções. É importante entender como as regras de segurança interagem com os dados hierárquicos.

Considere a situação em que cada documento da coleção de cities contém uma subcoleção de landmarks de referência. As regras de segurança se aplicam apenas no caminho combinado, portanto, os controles de acesso definidos na coleção de cities não se aplicam à subcoleção de landmarks de referência. Em vez disso, escreva regras explícitas para controlar o acesso às subcoleções:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

        // Explicitly define rules for the 'landmarks' subcollection
        match /landmarks/{landmark} {
          allow read, write: if <condition>;
        }
    }
  }
}

Ao aninhar instruções de match , o caminho da instrução de match interna é sempre relativo ao caminho da instrução de match externa. Os seguintes conjuntos de regras são, portanto, equivalentes:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

Curingas recursivas

Se você quiser que as regras se apliquem a uma hierarquia arbitrariamente profunda, use a sintaxe curinga recursiva, {name=**} . Por exemplo:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

Ao usar a sintaxe curinga recursiva, a variável curinga conterá todo o segmento de caminho correspondente, mesmo se o documento estiver localizado em uma subcoleção profundamente aninhada. Por exemplo, as regras listadas acima corresponderiam a um documento localizado em /cities/SF/landmarks/coit_tower , e o valor da variável do document seria SF/landmarks/coit_tower .

Observe, no entanto, que o comportamento dos curingas recursivos depende da versão das regras.

Versão 1

As regras de segurança usam a versão 1 por padrão. Na versão 1, curingas recursivos correspondem a um ou mais itens de caminho. Eles não correspondem a um caminho vazio, então match /cities/{city}/{document=**} corresponde a documentos em subcoleções, mas não na coleção cities , enquanto match /cities/{document=**} corresponde a ambos os documentos no coleção e subcoleções de cities .

Curingas recursivos devem vir no final de uma instrução de correspondência.

Versão 2

Na versão 2 das regras de segurança, curingas recursivos correspondem a zero ou mais itens de caminho. match/cities/{city}/{document=**} corresponde a documentos em qualquer subcoleção, bem como documentos na coleção de cities .

Você deve aceitar a versão 2 adicionando rules_version = '2'; no topo de suas regras de segurança:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

Você pode ter no máximo um curinga recursivo por instrução de correspondência, mas na versão 2, você pode colocar esse curinga em qualquer lugar na instrução de correspondência. Por exemplo:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

Se você usar consultas de grupo de coleção , deverá usar a versão 2, consulte protegendo consultas de grupo de coleção .

Declarações de correspondência sobrepostas

É possível que um documento corresponda a mais de uma declaração de match . No caso em que várias expressões de allow correspondem a uma solicitação, o acesso é permitido se qualquer uma das condições for true :

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

No exemplo acima, todas as leituras e gravações na coleção cities serão permitidas porque a segunda regra é sempre true , mesmo que a primeira regra seja sempre false .

Limites da regra de segurança

Ao trabalhar com regras de segurança, observe os seguintes limites:

Limite Detalhes
Número máximo de chamadas exist( exists() , get() e getAfter() por solicitação
  • 10 para solicitações de documento único e solicitações de consulta.
  • 20 para leituras de vários documentos, transações e gravações em lote. O limite anterior de 10 também se aplica a cada operação.

    Por exemplo, imagine que você crie uma solicitação de gravação em lote com 3 operações de gravação e que suas regras de segurança usem 2 chamadas de acesso a documentos para validar cada gravação. Nesse caso, cada gravação usa 2 de suas 10 chamadas de acesso e a solicitação de gravação em lote usa 6 de suas 20 chamadas de acesso.

Exceder qualquer um dos limites resulta em um erro de permissão negada.

Algumas chamadas de acesso a documentos podem ser armazenadas em cache e as chamadas armazenadas em cache não contam para os limites.

Profundidade máxima da instrução de match aninhada 10
Comprimento máximo do caminho, em segmentos de caminho, permitido em um conjunto de instruções de match aninhadas 100
Número máximo de variáveis ​​de captura de caminho permitidas em um conjunto de instruções de match aninhadas 20
Profundidade máxima de chamada de função 20
Número máximo de argumentos de função 7
Número máximo de associações de variáveis let por função 10
Número máximo de chamadas de função recursivas ou cíclicas 0 (não permitido)
Número máximo de expressões avaliadas por solicitação 1.000
Tamanho máximo de um conjunto de regras Os conjuntos de regras devem obedecer a dois limites de tamanho:
  • um limite de 256 KB no tamanho da fonte de texto do conjunto de regras publicada no Firebase console ou na CLI usando o firebase deploy .
  • um limite de 250 KB no tamanho do conjunto de regras compilado que resulta quando o Firebase processa a fonte e a torna ativa no back-end.

Próximos passos