I was just getting started with "complex" rules for firestore and wrote some unit tests before I started writing down the rules for my application.
I confronted probably a bug in the firestore rules emulator and wanted to make sure others have this problem too before reporting it.
What I wanted to achieve with the following test was an identification of anonymous users by the request attribute token.firebase.sign_in_provider
and prevent them from creating new files (since an anonymous user has a uid this criteria was insufficient).
# firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{prefix=**}/{document} {
allow read, write: if request.auth.token.admin == true;
// TODO Verify that this is not a bad practice
}
match /articles/{articleId} {
allow read: if request.auth.uid != null;
allow write: if "sign_in_provider" && request.auth.token.firebase
&& request.auth.token.firebase.sign_in_provider != "anonymous";
}
}
# firestore test
import * as firebase from "@firebase/testing";
import * as fs from "fs";
const projectId = "firestore-emulator-example";
const data = {
"title": "hello world"
}
const rules = fs.readFileSync("../firestore.rules", "utf8");
before(async () => {
await firebase.loadFirestoreRules({projectId, rules});
});
beforeEach(async () => {
await firebase.clearFirestoreData({projectId});
});
after(async () => {
await Promise.all(firebase.apps().map(app => app.delete()));
});
describe('Articles collection', () => {
it('should allow authenticated users to create an article', async () => {
const db = firebase.initializeTestApp({"projectId": projectId, "auth": {
"uid": "user-id",
"email": "us...@example.com",
"token": {
"sub": "user-id",
"aud": "test-project",
"firebase": {
"sign_in_provider": "password"
}
}
}}).firestore();
const articles = db.collection("articles");
await firebase.assertSucceeds(articles.doc("article-id").set(data));
});
});
P.S. I hope I abstracted everything correctly and provided all you need. Files
Error says:
FirebaseError: 7 PERMISSION_DENIED:
Property firebase is undefined on object. for 'create' @ L13
My test fails on the emulator but I get the expected behavior on the cloud firestore when deployed.
What I also though is that maybe the "token.firebase" attribute could be a protected token attribute that is only allowed and provided with a real authentication provider (in this case firebase) and therefore gets removed on test execution.