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.
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
- Firestore Security Rules Cookbook
- What does it mean that “Firestore security rules are not filters”?
[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>>
.
allow get
= Allow a single document readallow 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
.
Error values don't stop computation of conditions:
error && true => error
error && false => false
error || true => true
error || false => error
According to this post, the ternary expression has now been added.
<<boolean condition>>
? <<true-value>>
: <<false-value>>
request
= auth, time, path and create/update/delete data for this operationresource
= Document BEFORE this changerequest.resource
= Document AFTER this change ... if it were successful!
resource
= Requested documentresource['__name__']
= Document pathresource.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
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 typerequest.path
= Resource pathrequest.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.
- 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
String
,Integer
,Float
,Boolean
,Bytes
Number
=Integer
orFloat
Duration
,Timestamp
LatLng
List
,Map
,MapDiff
,Set
Path
,Request
,Response
-
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)
-
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 Syntaxstr.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 levelMapDiff.affectedKeys/addedKeys().changedKeys()/.removedKeys()/.unchangedKeys()
- e.g.
request.resource.data.diff(resource.data).affectedKeys().hasOnly(["a"]);
= was only field 'a' added/removed/updated ?
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 contentgetAfter(path: Path)
- Get what the document would be after this operation. Useful in batch writes.
request.time: Timestamp
- Time of requestrequest.resource.name
- Full file name (including path)request.resource.bucket
- Cloud Storage Buckctrequest.resource.metadata
- Map of custom propertiesrequest.resource.size
- File size in bytesrequest.resource.contentType
- MIME content type (e.g 'image/jpg')
resource.name: String
= Full file name (including path)resource.bucket: String
= Google Cloud Storage bucketresource.size: Integer
= File size in bytesresource.generation
- Object generation. Used for object versioning.resource.metageneration
- Object generation. Used for object versioning.resource.timeCreated: Timestamp
- create atresource.updated: Timestamp
- last update atresource.md5Hash: String
- MD5 Hashresource.crc32c: String
- CRC-32C Hash
Headers sent when downloading the file:
resource.etag
- ETagresource.cachecontrol
- Cache-Controlresource.contentDisposition
- Content-Dispositionresource.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
// Allow a read if the file was created less than one hour ago
allow read: if request.time < resource.timeCreated + duration.value(1, 'h');
// 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>;
}