Securely query data Stay organized with collections Save and categorize content based on your preferences.
This page builds on the concepts inStructuring Security Rules andWriting Conditions for Security Rules to explain howCloud Firestore Security Rules interact with queries. It takes a closer look at howsecurity rules affect the queries you can write and describes how to ensure yourqueries use the same constraints as your security rules. This page alsodescribes how to write security rules to allow or deny queries based on queryproperties likelimit andorderBy.
Rules are not filters
When writing queries to retrieve documents, keep in mind that security rules arenot filters—queries are all or nothing. To save you time and resources,Cloud Firestore evaluates a query against its potential result setinstead of the actual field values for all of your documents. If a query couldpotentially return documents that the client does not have permission to read,the entire request fails.
Note: This behavior applies to queries that retrieve one or more documents froma collection and not to individual document retrievals. When you use adocument ID to retrieve a single document,Cloud Firestore readsthe document and evaluates the request using your security rules and the actualdocument properties.Queries and security rules
As the examples below demonstrate, you must write your queries to fit theconstraints of your security rules.
Note: The same rules apply to both normal queries that return documents andaggregation queries. In other words,security rules control what conditions are allowed, not how data is returned.Secure and query documents based onauth.uid
The following example demonstrates how to write a query to retrieve documentsprotected by a security rule. Consider a database that contains a collection ofstory documents:
/stories/{storyid}
{ title: "A Great Story", content: "Once upon a time...", author: "some_auth_id", published: false}In addition to thetitle andcontent fields, each document stores theauthor andpublished fields to use for access control. These examples assumethe app usesFirebase Authentication to set theauthor fieldto the UID of the user who created the document. FirebaseAuthentication also populates therequest.auth variable inthe security rules.
The following security rule uses therequest.auth andresource.data variables to restrict read and write access for eachstory to its author:
servicecloud.firestore{match/databases/{database}/documents{match/stories/{storyid}{//Onlytheauthenticateduserwhoauthoredthedocumentcanreadorwriteallowread,write:ifrequest.auth!=null &&request.auth.uid==resource.data.author;}}}Suppose that your app includes a page that shows the user a list ofstorydocuments that they authored. You might expect that you could use the followingquery to populate this page. However, this query will fail, because it does notinclude the same constraints as your security rules:
Invalid: Query constraints do not matchsecurity rules constraints
// This query will faildb.collection("stories").get()The query failseven if the current user actually is the author of everystory document. The reason for this behavior is that whenCloud Firestore applies your security rules, it evaluates the queryagainst itspotential result set, not against theactual properties ofdocuments in your database. If a query couldpotentially include documentsthat violate your security rules, the query will fail.
In contrast, the following query succeeds, because it includes the sameconstraint on theauthor field as the security rules:
Valid: Query constraints match securityrules constraints
varuser=firebase.auth().currentUser;db.collection("stories").where("author","==",user.uid).get()Secure and query documents based on a field
To further demonstrate the interaction between queries and rules, the securityrules below expand read access for thestories collection to allow any user toreadstory documents where thepublished field is set totrue.
servicecloud.firestore{match/databases/{database}/documents{match/stories/{storyid}{//Anyonecanreadapublishedstory;onlystoryauthorscanreadunpublishedstoriesallowread:ifresource.data.published==true||(request.auth!=null &&request.auth.uid==resource.data.author);//Onlystoryauthorscanwriteallowwrite:ifrequest.auth!=null &&request.auth.uid==resource.data.author;}}}The query for published pages must include the same constraints as the securityrules:
db.collection("stories").where("published", "==", true).get()The query constraint.where("published", "==", true) guarantees thatresource.data.published istrue for any result. Therefore, this querysatisfies the security rules and is allowed to read data.
OR queries
When evaluating a logicalOR query (or,in, orarray-contains-any)against a ruleset,Cloud Firestore evaluates each comparison valueseparately. Each comparison value must meet the security rule constraints. Forexample, for thefollowing rule:
match/mydocuments/{doc}{allowread:ifresource.data.x >5;}Invalid: Query does not guarantee thatx > 5 for all potential documents
// These queries will failquery(db.collection("mydocuments"),or(where("x","==",1),where("x","==",6)))query(db.collection("mydocuments"),where("x","in",[1,3,6,42,99]))Valid: Query guarantees thatx > 5 for all potential documents
query(db.collection("mydocuments"), or(where("x", "==", 6), where("x", "==", 42) ) )query(db.collection("mydocuments"), where("x", "in", [6, 42, 99, 105, 200]) )Evaluating constraints on queries
Your security rules can also accept or deny queries based on their constraints.Therequest.query variable contains thelimit,offset,andorderBy properties of a query. For example, your security rulescan deny any query that doesn't limit the maximum number of documentsretrieved to a certain range:
allowlist:ifrequest.query.limit<=10;read rules intoget andlistrules. Rules forget apply to requests for singledocuments, and rules forlist apply to queries and requests for collections.The following ruleset demonstrates how to write security rules that evaluateconstraints placed on queries. This example expands the previousstoriesruleset with the following changes:
- The ruleset separates the read rule into rules for
getandlist. - The
getrule restricts retrieval of single documents to public documents ordocuments the user authored. - The
listrule applies the same restrictions asgetbut for queries. Italso checks the query limit, then denies any query without a limit or with alimit greater than 10. - The ruleset defines an
authorOrPublished()function to avoid codeduplication.
servicecloud.firestore{match/databases/{database}/documents{match/stories/{storyid}{//Returns`true`iftherequestedstoryis'published'//ortheuserauthoredthestoryfunctionauthorOrPublished(){returnresource.data.published==true||request.auth.uid==resource.data.author;}//Denyanyquerynotlimitedto10orfewerdocuments//Anyonecanquerypublishedstories//Authorscanquerytheirunpublishedstoriesallowlist:ifrequest.query.limit<=10&&authorOrPublished();//Anyonecanretrieveapublishedstory//Onlyastory's author can retrieve an unpublished story allow get: if authorOrPublished(); // Only a story'sauthorcanwritetoastoryallowwrite:ifrequest.auth.uid==resource.data.author;}}}Collection group queries and security rules
By default, queries are scoped to a single collection and they retrieve resultsonly from that collection. Withcollection group queries, you canretrieve results from a collection group consisting of all collections with thesame ID. This section describes how to secure your collection group queriesusing security rules.
Secure and query documents based on collection groups
In your security rules, you must explicitly allowcollection group queries by writing a rule for the collection group:
- Make sure
rules_version = '2';is the first line of your ruleset. Collectiongroup queries require thenew recursive wildcard{name=**}behavior of securityrules version 2. - Write a rule for your collection group using
match /{path=**}/[COLLECTION_ID]/{doc}.
For example, consider a forum organized intoforum documents containingposts subcollections:
/forums/{forumid}/posts/{postid}
{ author: "some_auth_id", authorname: "some_username", content: "I just read a great story.",}In this application, we make posts editable by their owners and readable byauthenticated users:
servicecloud.firestore{match/databases/{database}/documents{match/forums/{forumid}/posts/{post}{//Onlyauthenticateduserscanreadallowread:ifrequest.auth!=null;//Onlythepostauthorcanwriteallowwrite:ifrequest.auth!=null &&request.auth.uid==resource.data.author;}}}Any authenticated user can retrieve the posts of any single forum:
db.collection("forums/technology/posts").get()But what if you want to show the current user their posts across all forums?You can use acollection group query to retrieveresults from allposts collections:
varuser=firebase.auth().currentUser;db.collectionGroup("posts").where("author","==",user.uid).get()posts collection for fieldauthorand with collection group scope. If you haven't enabled this index, the querywill return an error link you can follow to create the required index.In your security rules, you must allow this query bywriting a read or list rule for theposts collection group:
rules_version='2';servicecloud.firestore{match/databases/{database}/documents{//Authenticateduserscanquerythepostscollectiongroup//Appliestocollectionqueries,collectiongroupqueries,and//singledocumentretrievalsmatch/{path=**}/posts/{post}{allowread:ifrequest.auth!=null;}match/forums/{forumid}/posts/{postid}{//Onlyapost'sauthorcanwritetoapostallowwrite:ifrequest.auth!=null &&request.auth.uid==resource.data.author;}}}Note, however, that these rules will apply to all collections with IDposts,regardless of hierarchy. For example, these rules apply to all of the followingposts collections:
/posts/{postid}/forums/{forumid}/posts/{postid}/forums/{forumid}/subforum/{subforumid}/posts/{postid}
Secure collection group queries based on a field
Like single-collection queries, collection group queries must also meet theconstraints set by your security rules. For example, we can add apublishedfield to each forum post like we did in thestories example above:
/forums/{forumid}/posts/{postid}
{ author: "some_auth_id", authorname: "some_username", content: "I just read a great story.", published: false}We can then write rules for theposts collection group based on thepublished status and the postauthor:
rules_version='2';servicecloud.firestore{match/databases/{database}/documents{//Returns`true`iftherequestedpostis'published'//ortheuserauthoredthepostfunctionauthorOrPublished(){returnresource.data.published==true||request.auth.uid==resource.data.author;}match/{path=**}/posts/{post}{//Anyonecanquerypublishedposts//Authorscanquerytheirunpublishedpostsallowlist:ifauthorOrPublished();//Anyonecanretrieveapublishedpost//Authorscanretrieveanunpublishedpostallowget:ifauthorOrPublished();}match/forums/{forumid}/posts/{postid}{//Onlyapost's author can write to a post allow write: if request.auth.uid == resource.data.author; } }}With these rules, Web, Apple, and Android clients can make the following queries:
Anyone can retrieve published posts in a forum:
db.collection("forums/technology/posts").where('published', '==', true).get()Anyone can retrieve an author's published posts across all forums:
db.collectionGroup("posts").where("author", "==", "some_auth_id").where('published', '==', true).get()Authors can retrieve all their published and unpublished posts across allforums:
varuser=firebase.auth().currentUser;db.collectionGroup("posts").where("author","==",user.uid).get()
Secure and query documents based on collection group and document path
In some cases, you might want to restrict collection group queries based ondocument path. To create these restrictions, you can use the same techniques forsecuring and querying documents based on a field.
Consider an application that keeps track of each user's transactionsamong several stock and cryptocurrency exchanges:
/users/{userid}/exchange/{exchangeid}/transactions/{transaction}
{ amount: 100, exchange: 'some_exchange_name', timestamp: April 1, 2019 at 12:00:00 PM UTC-7, user: "some_auth_id",}Notice theuser field. Even though we know which user owns atransactiondocument from the document's path, we duplicate this information in eachtransaction document because it allows us to do two things:
Write collection group queries that are restricted to documents that includea specific
/users/{userid}in their document path. For example:varuser=firebase.auth().currentUser;//Returncurrentuser's last five transactions across all exchangesdb.collectionGroup("transactions").where("user","==",user).orderBy('timestamp').limit(5)Enforce this restriction for all queries on the
transactionscollectiongroup so one user cannot retrieve another user'stransactiondocuments.
We enforce this restriction in our security rules and include data validationfor theuser field:
rules_version='2';servicecloud.firestore{match/databases/{database}/documents{match/{path=**}/transactions/{transaction}{//Authenticateduserscanretrieveonlytheirowntransactionsallowread:ifresource.data.user==request.auth.uid;}match/users/{userid}/exchange/{exchangeid}/transactions/{transaction}{//Authenticateduserscanwritetotheirowntransactionssubcollections//Writesmustpopulatetheuserfieldwiththecorrectauthidallowwrite:ifuserid==request.auth.uid &&request.data.user==request.auth.uid}}}Next steps
- For a more detailed example of role-based access control, seeSecuring DataAccess for Users and Groups.
- Read thesecurity rules reference.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-17 UTC.