For each security rule, is it necessary to always check auth !== null? It seems redundant to have to do this for every child rule.
I checked Firebase's own Firechat security rules and the enforcement is not consistent at all. There are rules that use auth.uid but do not check for null auth.
What happens if auth is null and auth.uid is used in the rule?
And what is the recommended practice regarding checking auth !== null?
The short answer is yes: by authenticating your users and writing security rules, you can fully restrict read / write access to your Firebase data. In a nutshell, Firebase security is enforced by server-side rules, that you author, and govern read or write access to given paths in your Firebase data tree.
How do they work? Firebase Security Rules work by matching a pattern against database paths, and then applying custom conditions to allow access to data at those paths. All Rules across Firebase products have a path-matching component and a conditional statement allowing read or write access.
Edit and update your rulesOpen the Firebase console and select your project. Then, select Realtime Database, Cloud Firestore or Storage from the product navigation, then click Rules to navigate to the Rules editor. Edit your rules directly in the editor.
Firebase Auth is a service that allows your app to sign up and authenticate a user against multiple providers such as (Google, Facebook, Twitter, GitHub and more). Firebase Auth provides SDKs with which you can easily integrate with web, Android, and iOS.
You need to check auth !== null
if you want the data restricted to any authenticated user.
You need to check for auth.uid == $uid
when you want the data restricted to the currently authenticated user. You don't need to check for auth == null && auth.uid != $uid
because auth.uid == $uid
will evaluate to false if the auth
variable is null. But you can still include both to be thorough.
So essentially, auth != null
is restricts the data to any authenticated user, and auth.uid != null
restricts to the single currently authenticated user.
Now for some extra curricular information.
Use the Bolt compiler to simplify common rules.
Security Rules are flexible, but they don't have much convenience for reproducing common rules. For that, you can use the Bolt compiler.
The Bolt compiler allows you to create types and assign them to paths in your Firebase database. These types act as schema. You can also create functions that abstract common rules.
I wrote a blog post on securing user data with Bolt. It goes through what you need to know to keep user data secured with types and functions in Bolt.
isCurrentUser(uid) = auth != null && auth.uid == uid;
isAuthenticated() = auth != null
path /users/$uid {
read() = isAuthenticated() // any authenticated user can read
write() = isCurrentUser($uid);
}
In the example above we reuse the isCurrentUser()
function three separate times. This will make changes moving forward much easier to deal with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With