es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué falla esta prueba de regla de seguridad para Firebase?

Tengo una colección “UserActivity”, donde cada “docId” es el ID del usuario. Bajo diferentes “docId”, tengo una subcolección “profileVisit” donde quiero poner algunos datos. Mis reglas de Firebase deberían permitir solo operaciones de creación. Es decir, el usuario puede crear una subcolección bajo “UserActivity/{userId}/profileVisit” solo si ha iniciado sesión y es el propietario de 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, la siguiente operación debería permitirse:

firebase
  .firestore()
  .collection("UserActivity")
  .doc(uid)
  .collection("profileVisit")
  .add({
    data: "some data",
  }); 

La prueba que he escrito es la siguiente:

it("Los usuarios pueden crear una subcolección profileVisit en su propio documento UsersActivity si han iniciado sesión", 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 para 'create'.

¿Puede alguien explicarme por qué falla mi prueba? ¿He escrito correctamente mi regla o es la prueba escrita de manera incorrecta?

EDICIÓN

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, cambie match /profileVisit a match /profileVisit/{id}. ¿Puede alguien explicarme por qué hay una diferencia y por qué necesito agregar {id} al final?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La razón por la que agregar {id} en la regla marca una diferencia es que la hace más específica. Sin {id}, la regla coincide con cualquier solicitud para crear una subcolección en /UsersActivity/{userId}/profileVisit, sin importar la identificación del documento de la subcolección que se está creando. Esto significa que la regla permite a cualquier usuario autenticado crear una subcolección bajo cualquier ID de usuario, siempre y cuando se especifique en la ruta del documento.

    Al agregar {id} a la regla, se vuelve más precisa y solo coincide con las solicitudes para crear una subcolección con una identificación de documento específica en /UsersActivity/{userId}/profileVisit/{id}. Esto asegura que la regla solo permita la creación de subcolecciones bajo el propio ID del usuario autenticado.

    Por lo tanto, cambiar la regla a:

    match /UsersActivity/{userId} {
      match /profileVisit/{id} {
        allow create: if userIsAuthenticated() && userOwnsResource(userId);
      }
    }
    

    la vuelve más restrictiva y aplica correctamente el requisito de que el usuario solo puede crear subcolecciones bajo su propio ID de usuario.

Comments are closed.