Firebase realtime DB rule based on data.child do not work - firebase-realtime-database

I like to retrieve the list of items only the ones its delete flag is false. but this setting does not work.
{
"rules": {
"items": {
".read": "data.child('isDelete').val() == false",
"$uid": {
".write": "auth != null && !data.exists()"
}
}
}
}
Here's a result from Rules playground request I tried.
Request details
{
"auth": null,
"resource": {
"key": "value"
},
"path": "/items",
"method": "get",
"time": "2022-07-07T09:24:31.042Z"
}
Result details
Line 4 (/items)
read: "data.child('isDelete').val() == false"
The data structure
items
- 1xxxxxxxxxx
title:"title text 1"
createdAt:"2022-06-05T04:21:57.322Z"
isDelete:false
- 2xxxxxxxxxxxxx
title:"title text 2"
createdAt:"2022-06-05T04:21:50.322Z"
isDelete:true
What is wrong?

I think you may be missing that rules are not filters on their own. All the rules do is check for any incoming operation whether it is allowed, and in your try from the playground you are trying to read all of /items, rather than just the items with isDelete set to false, to that isn't allowed.
There is no way to perform the necessary query from the playground, but in code you can get the items with this query:
ref.orderByChild("isDelete").equalTo(false)
Now the operation matches the condition in your rules, and is only trying to read data that it is allowed to, so the rules will allow the operation.
Update: I forgot that query-based rules in the Realtime Database actually require that you write the rule as this:
{
"rules": {
"items": {
".read": "query.orderByChild === 'isDelete' && query.equalTo === false",
...
Now the query only tries to retrieve non-deleted data, and the security rules correctly validate this.

Related

realtime-database rule validation is not working when updating data with null

When I try to update data in realtime-database with null, ".validate" in database.rules.json seems to be ignored.
I have a database.rules.json in the following format (not the exact same way, but this shows what I expect at least).
database.rules.json
"data": {
".read": "auth != null",
".write": "auth != null",
".validate": "newData.val() != null"
}
When I update realtime-database with
frontend.js
import { set } from 'firebase/database';
export class PublishService {
...
setWithData(value) {
// suppose dbReference has ref to "data"
// something like ref(this.database, "data")
set(this.dbReference, value);
}
}
where value == null,
I can still update realtime-database with null even though this isn't what I expect.
Is this how realtime-database is supposed to work?
If that's the case, is there any documentation that says that?
The .validate rule is not triggered for data deletions. From the documentation on .validate rules:
the validate definitions are ignored when data is deleted (that is, when the new value being written is null).
So you'll want to check for newData.exists() in the .write rule.

firebase rules allow only certain user to write key valus

i want to write firebase realtime database rule where certain user can only write cetain key
ex: user with UID underlined in red can write value of key franchise_active only
user with UID underlined in green can write value of key vendor_active only
both users can read
Sounds possible. Something like this should work:
{
"rules": {
"application_status": {
"$uid1": {
"$uid2": {
"franchise_active": {
".write": "auth.uid === $uid1"
},
"vendor_active": {
".write": "auth.uid === $uid2"
}
}
}
}
}
}

firebase security-rules write access to only one specific field

is it possible to give update access to only one specific field ?
users
+ gaglajasdfer32fasfa
- Name: Luke // not allowed to update
- likes: 3 // allowed to update
You will have to specify the rule for each field in that case as shown below:
{
"rules": {
"users": {
"$uid": {
"Name": {
".write": "!data.exists()"
}
}
}
}
}
!data.exists() allows write operation only when it's absent now and hence allowing "Create" operations only and not "update" or "delete".
Checkout the documentation to learn more about security rules.

Firebase realtime DB - Create rule that limits size of child object

I've got a Realtime Database where users can write data to a certain key. However, I want to avoid a potentially malicious user from inserting a huge amount of data, without creating any new middleware.
Here are my rules right now:
{
"rules": {
/*
* Only let people read a specific name
* Only let people write "$user": <public info json> or "$user": null
*/
"$user": {
".read": "true",
".write": "auth.uid === $user"
".validate": "newData.val().length <= 123456 || newData.val() == null"
}
}
}
But this incorrectly rejects a write if the data at databaseurl/$user is a child object rather than a string, even if the JSON string representation of the child is below the length size.
How can I restrict the length of a child object, if the child is more than a simple string?
Thanks!

How can you observe a snapshot of a upper level child w/o overriding the lower child rules?

JSON
"users" : {
"02PdiNpmW3MMyJt3qPuRyTpHLaw2" : {
"Coordinates" : {
"latitude" : -24.809620667034363,
"longitude" : 28.321706241781342
},
"Education" : "6", ........./// here are 10 Childs further on same level as education
"Music"
The current rules
{
"rules": {
".read": false,
".write": false,
, "users": {
"$uid": {
"Education" :{
".read": "$uid == auth.uid",
".write": "$uid == auth.uid"
}
According to my understanding, if I make users read rule for authorized users, it will override the education rule. This below is where users read rule is needed
let artist = Database.database().reference().child("users").queryOrdered(byChild: "music").queryStarting(atValue:dateToday.timeIntervalSince1970*1000)
artist.observe(DataEventType.value, with: { snapshot in
Update: I had a typo "users" at the rules
In general indeed the rule is that if you grant somebody read (or write) access to a node, they have the same access to all data under that node. So you can't just say ".read": true on /people as that will them to read the entire node.
What you can do is specify what query is allowed in your security rules. So to allow every to read all nodes with the given music value, you could do:
"baskets": {
".read": "query.orderByChild == 'music' &&
query.equalTo > 1354867200000"
}
A few things to keep in mind here:
I hard-coded it here, but you will have to calculate the value for the filter in your rules somehow based on the now variable.
You can only filter on a single value, so you can't filter on both music and uid. You may be able to merge the two values into a single property and order/filter on that. For more on this see: Query based on multiple where clauses in Firebase

Resources