Home > Mobile >  Why does this test for firebase security rule fails?
Why does this test for firebase security rule fails?

Time:12-14

I have a collection UserActivity, where each docId is the id of the user. Under different docIds I have subcollection profileVisit where I want to put some data My firebase rule, should allow only create operation. That is, user can create subcollection under Useractivity/{userId}/profileVisit only if they are logged in and they own this resource. So my firebase rule is the following:

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
    }

That is, thefollowing operation should be allowed:

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

The test which I wrote is the following:

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" }));
  });

This test fails with: FirebaseError: 7 PERMISSION_DENIED: false for 'create'

Can someone explain to me why does my test fail? Have I written my rule correctly or is it the test written in the wrong way?

EDIT

Seems that changing the rule to:

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

allows my test to pass. That is I changed match /profileVisit to match /profileVisit/{id} { Can someone explain me why there is a difference and why I need to add {id} in the end?

CodePudding user response:

As you discovered yourself in your edit, this doesn't do anything:

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

The match /profileVisit matches the profileVisit collection, but no documents in that, so it's a noop.

To make it match any document, use:

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