I'm trying to secure my Documents with a availability status, that can be public or private. Everybody can read public Documents and private Documents can be read by Users who have created the Document (meaning creatorUid is set to the user's uid).
These are my rules:
match /Routines/{document} {
allow read: if resource.data.availability == "public" || (resource.data.availability == "private" && resource.data.creatorUid == request.auth.uid);
allow write: if true;
}
I have created some tests to see if my rules work:
describe.only("Routine Routine Rules", () => {
const userAuthA = { uid: "user123", email: "userA@test.com" };
const demoRoutinePrivate = {
id: "DemoRoutine",
title: "Demo Routine",
availability: "private",
creatorUid: userAuthA.uid,
exercises: []
}
it("Authors can read private routines", async () => {
const admin = getAdminFirestore();
await admin.collection("Routines").doc(demoRoutinePrivate.id).set(demoRoutinePrivate);
const db1 = getAuthedFirestore(userAuthA);
const routines1 = db1.collection("Routines").where("creatorUid", "==", userAuthA.uid);
const routine1 = db1.collection("Routines").doc(demoRoutinePrivate.id);
await firebase.assertSucceeds(routines1.get());
await firebase.assertSucceeds(routine1.get());
});
});
However, I get this error:
FirebaseError:
Property availability is undefined on object. for 'list' @ L33
I'm pretty certain that my Document has the availabilty property set, so I don't understand the error.
I figured it out. I had an error in my query.
const routines1 = db1.collection("Routines").where("creatorUid", "==", userAuthA.uid);
the correct query is:
const routines1 = db1.collection("Routines").where("availability", "==", "private").where("creatorUid", "==", userAuthA.uid);
although the original error message is not very helpful...