如何在保留现有数据库结构的前提下,限制读写规则至节点创建者?
Hey there! Let's break down how to set up Firebase Security Rules that enforce exactly what you need: users can only read and write the buildings and depts nodes they created themselves.
First, let's recap your core database structure to make sure we're aligned:
{
"buildings" : {
"-L9HIbKu5fIe8rfoePgi" : {
"address" : "",
"hasDepts" : { "-L9HIdScisDItysCnMlm" : true },
"name" : "building 1",
"ownerID" : "6hwNde08Wuaa9bfReR28niSbOsF3"
}
},
"depts" : {
"-L9HIdScisDItysCnMlm" : {
"inBuilding" : "-L9HIbKu5fIe8rfoePgi",
"name" : "..."
}
}
}
The key here is using the ownerID field on each building to tie it to a user, then linking departments to their parent building to inherit that ownership permission.
Full Security Rules Implementation
Here's the complete rule set that enforces your requirements:
{ "rules": { "buildings": { "$buildingId": { ".read": "request.auth != null && request.auth.uid == data.child('ownerID').val()", ".write": "request.auth != null && ( // Allow creating a new building only if ownerID is set to the current user's UID (newData.exists() && !data.exists() && newData.child('ownerID').val() == request.auth.uid) || // Allow updating/deleting an existing building only if it belongs to the current user (data.exists() && data.child('ownerID').val() == request.auth.uid) )" } }, "depts": { "$deptId": { ".read": "request.auth != null && root.child('buildings').child(data.child('inBuilding').val()).child('ownerID').val() == request.auth.uid", ".write": "request.auth != null && ( // Allow creating a new dept only if its linked building belongs to the current user (newData.exists() && !data.exists() && root.child('buildings').child(newData.child('inBuilding').val()).child('ownerID').val() == request.auth.uid) || // Allow updating/deleting a dept only if its linked building still belongs to the current user (data.exists() && root.child('buildings').child(data.child('inBuilding').val()).child('ownerID').val() == request.auth.uid) )" } } } }
How This Works
Let's break down each section:
Buildings Rules
- Read Access: First, we ensure the user is authenticated (
request.auth != null). Then we check that the current user's UID matches theownerIDstored on the building node. This guarantees only the creator can view their building. - Write Access: We split this into two cases:
- Creating a building: The user must set the
ownerIDto their own UID. This prevents users from creating buildings assigned to someone else. - Updating/deleting a building: The user can only modify buildings that already have their UID as
ownerID.
- Creating a building: The user must set the
Depts Rules
Since departments are tied to a building via the inBuilding field, we validate against the parent building's ownership:
- Read Access: Start with authentication, then traverse up to the linked building using
root.child('buildings').child(data.child('inBuilding').val())and check if itsownerIDmatches the current user's UID. - Write Access: Similar to buildings, but tied to the linked building:
- Creating a dept: The linked building must belong to the current user, so they can't create departments in someone else's building.
- Updating/deleting a dept: The linked building still has to belong to the user, preventing them from reassigning a dept to another user's building after creation.
Extra Tips
- Enforce OwnerID Immutability: If you want to prevent users from changing the
ownerIDof a building after creation, add this check to the building's.writerule:&& (!newData.child('ownerID').exists() || newData.child('ownerID').val() == data.child('ownerID').val()) - Client-Side Validation: Make sure your frontend code automatically sets the
ownerIDto the current user's UID when creating a building (you can get this from Firebase Auth'suser.uid). This avoids failed writes due to missing or incorrectownerIDvalues.
内容的提问来源于stack exchange,提问作者Joao Alves Marrucho

