16

I'm almost good with all my tests for Firestore Rules. But, I still need to test some path for the admin.

The admin in my app is not the Firebase admin, it's an user with privileges set like this in its customClaims :

claims: {admin: true}

How I can mock users customClaims with the npm package @firebase/testing ? I can't figure it out.

Thanks

PS: Below, what I'm currently doing.

export default class TestApplication {

  public static getFirestoreInstance(auth, projectId: string): firebase.firestore.Firestore {
    return firebase
       .initializeTestApp({projectId, auth})
       .firestore();
  }
}


describe(){
    const defaultAuthUser = {uid: "alice", email: "alice@example.com", "token": {"admin": true};

    before(done => {
        currentProjectId = TestUtils.getRandomId();
        TestApplication.useFirestoreRules(currentProjectId, rules)
          .then(() => done())
          .catch(done);
    });

    it("I should be able to get another user if I'm an admin", () => {
      return firebase.assertSucceeds(
        TestApplication.getFirestoreInstance(defaultAuthUser, currentProjectId)
          .collection(FirebaseReference.USERS_REF)
          .doc(otherUserId)
          .get()
      );
    }).timeout(5000);
}
Spoke44
  • 968
  • 10
  • 24

3 Answers3

26

Custom claims can be passed as top-level fields within the auth object:

firebase.initializeTestApp({
  projectId: "my-test-project",
  auth: { uid: "alice", my_custom_claim: "foo" }
});

In the example from the question, this line:

const defaultAuthUser = {uid: "alice", email: "alice@example.com", "token": {"admin": true};

Should be changed to:

const defaultAuthUser = {uid: "alice", email: "alice@example.com", admin: true};
Chris Pick
  • 570
  • 4
  • 7
  • 1
    Had the same issue and turns out @Chris's solution solves the problem. I think this should be accepted as a correct answer. – Tadej Mar 23 '20 at 22:13
9

I think the answer above could be a little more specific. The custom claim needs to be on the auth object when initializing the app. But when checking the custom claims in the security rules the custom claims are in the 'token' property (request.auth.token.admin).

Initializing the app:

firebase.initializeTestApp({
  projectId: "my-test-project",
  auth: { uid: "alice", my_custom_claim: "foo", admin: true }
});

firebase.rules

...
match /posts/{postId} {
  allow update: if request.auth.token.admin 
}
...
bsteinemann
  • 91
  • 1
  • 1
-1

I suppose you are using this approach: https://firebase.google.com/docs/firestore/security/test-rules-emulator#run_local_tests

So somewhere in your test code you have:

  firebase.initializeTestApp({
   projectId: "my-test-project",
   auth: { uid: "alice", email: "alice@example.com" }
 });

In this auth field you can mock your custom claims as:

{
  "uid": "alice",
  "email": "alice@example.com",
  "token": {
    "admin" :true
  }
}

Then you can use request.auth.token.admin in your rules. I tried this on storage, but same/similar should apply to Firestore too.

Revolution88
  • 688
  • 5
  • 17
  • Thanks, but I already tried this. It seems to not work and I can't find any documentation about it. I tried `claims`, `customClaims` too instead of `token` – Spoke44 Dec 05 '18 at 16:09
  • I tried this on storage and it works through simulator. I will try on firestore and let you know. Did you try to put customClaims field inside token? – Revolution88 Dec 10 '18 at 09:12