Hello everyone, the situation is the last time I encountered a task related to the firebase rules
so it took quite a bit of time to learn this task. So I will write this article to help people spend less time finding reading materials.
First, let’s find out what Cloud Firestore Security Rules
are.
Cloud Firestore Security Rules
is a tool to determine access control to Firestore
. You do not have to worry about generating authentication or authentication codes for your database. In the Cloud Firestore Security Rules
dashboard, identify the results that match your collections
or subcollections
and enable each of them to manage access to Firestore
.
Okay, let’s get to the main content.
1. Block access to Firestore
The code below is used to lock any activity on Firestore
.
1 2 3 4 | match <span class="token operator">/</span> <span class="token punctuation">{</span> document <span class="token operator">=</span> <span class="token operator">**</span> <span class="token punctuation">}</span> <span class="token punctuation">{</span> allow read <span class="token punctuation">,</span> write <span class="token punctuation">:</span> <span class="token keyword">if</span> <span class="token boolean">false</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
{document=**}
is used to match all collection and subcollection
in Firestore
.
With false condition to prevent all operations.
2. Allow access to Firestore
Just like the code in Part 1, if you want to allow all access on Firestore
we just need to write as below.
1 2 3 4 | match <span class="token operator">/</span> <span class="token punctuation">{</span> document <span class="token operator">=</span> <span class="token operator">**</span> <span class="token punctuation">}</span> <span class="token punctuation">{</span> allow read <span class="token punctuation">,</span> write <span class="token punctuation">;</span> <span class="token comment">// or allow read, write: if true;</span> <span class="token punctuation">}</span> |
{document=**}
is used to match all collection and subcollection in Firestore.
If true, you can allow all operations.
3. Special security rules for a specific collection
1 2 3 4 | match /{collectionName}/{documentId} { allow read, write : if collectionName != "users"; } |
The code above means: To be entitled to read
, write
if collectionName
other "users"
.
4. Access for authenticated users
In security rules, we have access to the request object. The request includes authentication information so you can use it to verify that the requested user is authenticated.
1 2 3 4 | match /products/{productId} { allow read: if request.auth != null; } |
The above code applies to all collection products
, if the user has been authenticated
can read
the information of the collection products
.
5. Access for a specific user
This security rule allows read
or write
in case the user
has the same uid
as the userId
. The most common example of using this security rule is on a user collection whose user ID
equal to the ID
in the colllection
.
1 2 3 4 | match /users/{userId} { allow read: if request.auth.uid == userId; } |
userId – is used to compare with the id of the requested user.
6. Access for users who exist in the document list
Usage of resources stored in Firestore
or available in write operations. A resource object includes:
- name : The full path of the document.
- data : All document data.
- id : Document id.
1 2 3 4 | match /posts/{postId} { allow read: if request.auth.uid in resource.data.contributors; } |
Let me explain a little bit of the above code, we use resource.data
to get all the contributors and verify who reuqest exists in the array.
- request.auht.uid : The id information of the user who is requesting.
- resource.data.contributors : List of users who are in the
collection contributors
, they are saved asarray
.
7. Does the test object exist?
When defining a security rule, we can create a condition by using the built-in function
to determine if a document exists in another collection
. It’s easy to simply use the path as a function argument.
Syntax: exists(/databases/$(database)/documents/collectionName/$(documentId))
. Inside:
- $ (database) : The parameter specifies an instance of the database available as a wildcard in the main lines of the
Cloud Firestore Security Rules
file.
match /databases/{database}/documents
- collectionName : The name of the
collection
you want to verify. - documentId : The
ID
of thedocument
is required.
For example:
1 2 3 4 5 | match <span class="token operator">/</span> notificationStrategy <span class="token operator">/</span> <span class="token punctuation">{</span> strategyId <span class="token punctuation">}</span> <span class="token punctuation">{</span> allow write <span class="token punctuation">:</span> <span class="token keyword">if</span> <span class="token function">exists</span> <span class="token punctuation">(</span> <span class="token operator">/</span> databases <span class="token operator">/</span> <span class="token function">$</span> <span class="token punctuation">(</span> database <span class="token punctuation">)</span> <span class="token operator">/</span> documents <span class="token operator">/</span> user <span class="token operator">/</span> <span class="token function">$</span> <span class="token punctuation">(</span> request <span class="token punctuation">.</span> auth <span class="token punctuation">.</span> uid <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
write
permission will be allowed when a user’s uid
exists ( request.auth.uid
is the uid
of the uid
user
) in the user collection
.
8. Access another document
Another method available in Cloud Firestore Security Rules
is the get()
. This method is similar to the exists()
only has different results. The get()
will give us access to the document’s data by calling get(path).data
.
1 2 3 4 5 6 7 8 9 10 11 | match <span class="token operator">/</span> post <span class="token operator">/</span> <span class="token punctuation">{</span> postId <span class="token punctuation">}</span> <span class="token punctuation">{</span> allow update <span class="token punctuation">,</span> <span class="token keyword">delete</span> <span class="token punctuation">:</span> <span class="token keyword">if</span> <span class="token function">isPostOwner</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token function">isAdmin</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">isPostOwner</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> resource <span class="token punctuation">.</span> data <span class="token punctuation">.</span> ownerId <span class="token operator">==</span> request <span class="token punctuation">.</span> auth <span class="token punctuation">.</span> uid <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">isAdmin</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">get</span> <span class="token punctuation">(</span> <span class="token operator">/</span> databases <span class="token operator">/</span> <span class="token function">$</span> <span class="token punctuation">(</span> database <span class="token punctuation">)</span> <span class="token operator">/</span> documents <span class="token operator">/</span> user <span class="token operator">/</span> <span class="token function">$</span> <span class="token punctuation">(</span> request <span class="token punctuation">.</span> auth <span class="token punctuation">.</span> uid <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> data <span class="token punctuation">.</span> role <span class="token operator">==</span> <span class="token string">"ADMIN"</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
The right to update
, delete
is allowed when the user
is request
is the author of the post or the admin
of the system (i.e. resource.data.ownerId == request.auth.uid hoặc get(path).data.role == "ADMIN"
).
Okay! Above are my share of the basic principles in Cloud Firestore Security Rules
and explanatory examples. Hope can help everyone.
Reference: https://medium.com/@khreniak/cloud-firestore-security-rules-basics-fac6b6bea18e