firestore-quickreference
firestore-quickreference copied to clipboard
Quick Reference for Firebase Security
FireStore & FireStorage Security Rules - Quick Reference
I found the official Firebase references for security rules a bit slow to use (too much detail to scan) so I created this condensed Quick Reference as a faster way to look up methods, properties and function names and as reminder of constructs and patterns. Since Firebase developers are already JavaScript coders, you'll likely already be very familier with the meaning of the most of the functions and method names available in FireStore and StoreStorage security rules languages.
This is still a work in progress so feel free to contribute or fix but please retain the compact format. I think it really needs some "best practice" pattern examples - perhaps on a separate page.
NOTE: This is NOT an official Firebase reference and may be incorrect or out of date. By using this quick reference you agree that it is solely your responsability to confirm the validity and correctness of this information.
Official References
Firestore
- Guide: Firebase Security Rules
- Reference: Firestore Security Rules
- Blog Jun 17, 2020: Firestore Security Rules Improvements
- Release Notes
- Library that provides programmatic access to test Firestore security rules.
Storage
Tech Support
Other Resources
- Firestore Security Rules Cookbook
- What does it mean that “Firestore security rules are not filters”?
Videos
Security Rules
[rules_version = <<version>>]
service <<service>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
-
<<version>>
::='2'
-
<<service>>
::=cloud.firestore
|cloud.firestorage
-
<<path>>
::= database or storage location -
<<methods>>
::=get
|list
|create
|update
|delete
|read
|write
-
<<condition>>
::== A condition based onrequest
&resource
objects and bound variables from<<path>>
.
Permissions Methods
-
allow get
= Allow a single document read -
allow list
= Allow collection reads and queriesdb.collection("users").orderBy("name")
-
allow read
= Allowget
andlist
-
allow create
- AllowdocRef.set()
orcollectionRef.add()
-
allow update
- AllowdocRef.update()
ordocRef.set()
-
allow delete
- AllowdocRef.delete()
-
allow write
- Allowcreate
,update
ordelete
.
Conditions and Errors
Error values don't stop computation of conditions:
error && true => error
error && false => false
error || true => true
error || false => error
Ternary
According to this post, the ternary expression has now been added.
<<boolean condition>>
? <<true-value>>
: <<false-value>>
FireStore Validation
-
request
= auth, time, path and create/update/delete data for this operation -
resource
= Document BEFORE this change -
request.resource
= Document AFTER this change ... if it were successful!
FireStore Resource
-
resource
= Requested document -
resource['__name__']
= Document path -
resource.id
= Document key- e.g.
resource['__name__'] == /databases/(default)/documents/collection/$(resource.id)
- e.g.
-
resource.data.{field}
= Current field values (field => value) -
request.resource.data.{field}
= Pending document state after operation
FireStore Request
-
request.resource.data
- field values AFTER the requested opertion if successful. -
request.auth
-
request.auth.uid
-
request.auth.token.email
-
request.auth.token.email_verified
-
request.auth.token.phone_number
-
request.auth.token.name
-
request.auth.token.firebase.identities
-
request.auth.token.firebase.sign_in_provider
-
request.{get|list|create|update|delete}
= Operation type -
request.path
= Resource path -
request.query.{limit|offset|orderBy}
= Optional Query- e.g.
allow list: if request.query.limit <= 50
- e.g.
-
request.time
= Time of request- e.g.
request.time == request.resource.data.updateAt
- e.g.
Custom Claims
- Sets values in
request.auth.token.<key>
- Control Access with Custom Claims and Security Rules
Reserved claim keys:
-
amr
,at_hash
,aud
,auth_time
,azp
,c_hash
,cnf
,exp
,firebase
,iat
,iss
,jti
,nbf
,nonce
,sub
Types
-
String
,Integer
,Float
,Boolean
,Bytes
-
Number
=Integer
orFloat
-
Duration
,Timestamp
-
LatLng
-
List
,Map
,MapDiff
,Set
-
Path
,Request
,Response
Namespace Functions
-
debug(value)
- Returnsvalue
. Use in conditions. Outputs tofirestore-debug.log
in Emulator only. -
maths.abs()/.ceil()/.floor()/.isInfinite()/.isNan()/.pow()/.round()/.sqrt()
, -
timestamp.date(year, month, day): Timestamp
-
timestamp.value(epoch): Timestamp
-
duration.time(hours, mins, secs, nanos)
-
duration.value(integer, unit)
unit is w=weeks,d=days,h=hours,m=minutes,s=seconds,ms=millisecs,ns=nanosecs -
latlng.value(lat, lng): LatLng
,LatLng.distance(): Float
,LatLng.latitude():Float
,LatLng.longiture():Float
-
hashing.crc32(bytes)/.csc32c(bytes)/.md5(bytes)/.sha256(bytes)
-
hashing.crc32(string)/.csc32c(string)/.md5(string)/.sha256(string)
Classes
-
String: e.g.
string(true) == "true"
,string(1) == "1"
,string(2.0) == "2.0"
,string(null) == "null"
-
str.lower()
,str.upper()
, -
str.matches(re)
- re = Google RE Syntax -
str.replace(re, sub)
-
str.size()
,str.split()
,str.trim()
-
str.toUtf8(): Bytes
-
-
Timestamp
-
timestamp + duration
-
timestamp - duration
-
duration + timestamp
-
timestamp.date()/.time()
-
timestamp.year()/.month()/.day()
-
timestamp.hours()/.minutes()/.seconds()/.nanos()
-
timestamp.toMillis()/.dayofYear()
-
timestamp.dayofWeek()/.dayofYear()
-
-
Duration
-
timestamp - timestamp
-
duration + duration
-
duration - duration
- Use Namespace functions to create a Duration
-
-
List:
- e.g.
['a', 'b']
-
list.hasAll(list): Set
-
list.hasAny(list): Boolean
-
list.hasOnly(list): Boolean
-
list.join(separator): String
-
list.size(): Integer
-
list.toSet(): Set
- e.g.
-
Set:
- e.g.
['a', 'b'].toSet()
- How to create a Set -
set.difference(set): Set
-
set.hasAll(list): Set
-
set.hasAny(list): Boolean
-
set.hasOnly(list): Boolean
-
set.intersection(set): Set
-
set.union(set): Set
-
set.size(set): Integer
- e.g.
-
Map:
-
map.get(key, default): Value
-
map.keys(): List
-
map.values(): List
-
map.size(): Integer
-
map.diff(map): MapDiff
- used to validate changes at the field level-
MapDiff.affectedKeys/addedKeys().changedKeys()/.removedKeys()/.unchangedKeys()
- e.g.
request.resource.data.diff(resource.data).affectedKeys().hasOnly(["a"]);
= was only field 'a' added/removed/updated ?
-
-
FireStore only functions:
-
exists(path: Path)
- Does document exist?- e.g.
allow write: if exists(/databases/$(database)/documents/things/other)
- e.g.
-
existsAfter(path: Path)
- Will document exist after this operation?- same as
getAfter(path) != null
- same as
-
get(path: Path)
- Get Document content -
getAfter(path: Path)
- Get what the document would be after this operation. Useful in batch writes.
Storage API - Request
-
request.time: Timestamp
- Time of request -
request.resource.name
- Full file name (including path) -
request.resource.bucket
- Cloud Storage Buckct -
request.resource.metadata
- Map of custom properties -
request.resource.size
- File size in bytes -
request.resource.contentType
- MIME content type (e.g 'image/jpg')
Storage API - Resource
-
resource.name: String
= Full file name (including path) -
resource.bucket: String
= Google Cloud Storage bucket -
resource.size: Integer
= File size in bytes -
resource.generation
- Object generation. Used for object versioning. -
resource.metageneration
- Object generation. Used for object versioning. -
resource.timeCreated: Timestamp
- create at -
resource.updated: Timestamp
- last update at -
resource.md5Hash: String
- MD5 Hash -
resource.crc32c: String
- CRC-32C Hash
Headers sent when downloading the file:
-
resource.etag
- ETag -
resource.cachecontrol
- Cache-Control -
resource.contentDisposition
- Content-Disposition -
resource.contentEncoding
- Content-Encoding of the file (for example 'gzip') -
resource.contentLanguage
- Content-Language of the file content (e.g. 'en' or 'es') -
resource.contentType
- MIME Content-Type (e.g 'image/jpg') -
resource.metadata: Map<String, String>
- Developer provided fields
Storage API - Samples
// Allow a read if the file was created less than one hour ago
allow read: if request.time < resource.timeCreated + duration.value(1, 'h');
Storage Rules
// Specify the Storage service with $bucket name
service firebase.storage {
match /b/{bucket}/o {
...
}
}
allow read;
allow write;
allow read, write;
allow read: if <condition>;
allow write: if <condition>;
// Allow read at "path/to/object" if condition evaluates to true
match /path {
match /to {
match /object {
allow read: if <condition>;
}
}
}
// Allow read at any path "/path/*/newPath/*", if condition evaluates to true
match /path/{str1} { // Binds str1: String
match /newPath/{str2} { // Binds str2: String
// Matches "path/to/newPath/newObject" or "path/from/newPath/oldObject"
allow read: if <condition>;
}
}
// Allow read at any path "/**", if condition evaluates to true
match /{path1=**} { // Binds path1: Path
// Matches anything at or below this, from "path", "path/to", "path/to/object", ...
allow read: if <condition>;
}