I'm making a query to firestore using:
setDoc(doc(db, "vendors", this.vendorId), {
title: "test listing",
vendorId: this.vendorId
}, {merge: true}).then(i => {
console.log("i", i)
}).catch(e => {
console.log("error", e)
})
I have 2 collections the first one has a sub collection
Collection users/${userId}
{
"userId": "123.uuu",
"role": "vendor"
}
Sub collection users/${userId}/vendors/${vendorId}
{
"user": "123.uuu",
"vendor": "123..vvv"
}
The second collection is Collection vendors/${vendorId}
{
"userId": "123.uuu",
"role": "vendor"
}
I want to be able to update the second collection vendors/${vendorId} but only if the users sub collection users/${userId}/vendors/${vendorId} exists and therefore has access to it.
The below rule doesn't work - returns FirebaseError: Missing or insufficient permissions.
match /vendors/{vendorId}{
allow update: if get(/databases/$(database)/documents/users/$(request.auth.uid)/vendors/$(vendorId)).data.user == request.auth.uid
}
CodePudding user response:
The allow update
will allow update operations only i.e. the document must already exist. Since you are using using setDoc()
, that means a new document is being created if it doesn't exist already. Try allowing create
as well:
allow create, update: if ....;
Checkout the documentation on Security Rules and also this Firecast
CodePudding user response:
According to @Doug Stevenson: "Security rules don't mean anything unless paired with code that makes the query.", you can try to follow the example code below that works upon replicating on my end:
// Where the user.uid is the users document id;
// and the vendorId is the value of the "user" under vendors' sub-collection
const userRef = doc(db, "users", {user.uid}, "vendors", {vendorId});
const userSnap = await getDoc(userRef);
if (userSnap.exists()){
// Where the vendorId is the value of the user under vendors' collection
await setDoc(doc(db, "vendors", {vendorId}), {
title: "test listing",
vendorId: this.vendorId
},
{merge: true}).catch(e => {
console.log("error", e);
})
}
else{
// doc.data() will be undefined in this case
console.log("No such document!");
}
Additionally, following the answer of @Dharmaraj, you can try this rule:
match /vendors/{vendorId} {
// 'user' field in collection 'vendors', and users' sub-collection 'vendors', should have the same value for this rule to work
// this will check 'vendors' and users' sub-collection 'vendors' user field if its the same or not
allow read, create, update: if resource.data.user == request.auth.uid && request.auth.uid != null
}
For more information, you can check the guide below:
How to fix Firestore Error: PERMISSION_DENIED: Missing or insufficient permissions