Tengo una colección UserActivity , donde cada docId es la identificación del usuario. Bajo diferentes docId s, tengo un perfil de subcolección profileVisit donde quiero poner algunos datos. Mi regla de firebase, debería permitir solo crear operaciones. Es decir, el usuario puede crear una subcolección en Useractivity/{userId}/profileVisit solo si ha iniciado sesión y posee este recurso. Entonces mi regla de firebase es la siguiente:
match /UsersActivity/{userId} { match /profileVisit { allow create: if userIsAuthenticated() && userOwnsResource(userId); } } function userIsAuthenticated () { return request.auth.uid != null; } function userOwnsResource (userId) { return request.auth.uid == userId }Es decir, se debe permitir la siguiente operación:
firebase .firestore() .collection("UserActivity") .doc(uid) .collection("profileVisit") .add({ data: "some data", });La prueba que escribí es la siguiente:
it("Users can create subcollection profileVisit under their own UsersActivity document if they are signed in", async () => { const db = getFirestore(auth); const userDoc = db .collection("UsersActivity") .doc(myId) .collection("profileVisit"); await firebase.assertSucceeds(userDoc.add({ data: "data" })); }); Esta prueba falla con: FirebaseError: 7 PERMISSION_DENIED: false for 'create'
¿Alguien puede explicarme por qué falla mi prueba? ¿He escrito mi regla correctamente o la prueba está escrita de forma incorrecta?
EDITAR
Parece que cambiar la regla a:
match /UsersActivity/{userId} { match /profileVisit/{id} { allow create: if userIsAuthenticated() && userOwnsResource(userId); } } permite que mi prueba pase. Es decir, cambié match /profileVisit para que match /profileVisit/{id} { ¿Puede alguien explicarme por qué hay una diferencia y por qué necesito agregar {id} al final?
Como te descubriste en tu edición, esto no hace nada:
match /UsersActivity/{userId} { match /profileVisit { allow create: if userIsAuthenticated() && userOwnsResource(userId); } } La match /profileVisit coincide con la colección profileVisit , pero no contiene documentos, por lo que es un noop.
Para que coincida con cualquier documento, utilice:
match /UsersActivity/{userId} { match /profileVisit/{docId} { allow create: if userIsAuthenticated() && userOwnsResource(userId); } }