我正在将此tutorial用于Firestore安全规则。我从存储库中提取了代码,它与视频的代码匹配。
我更改了public class MainPanelTest extends ApplicationTest {
Pane toTest;
boolean pressed = false;
@Override
public void start(Stage stage) {
toTest= new VBox(new Canvas(800,800));
toTest.setOnKeyPressed(e -> {
System.out.println("Pressed");
pressed = true;
});
stage.setScene(new Scene(toTest));
stage.show();
toTest.requestFocus();
}
@Test
public void test_keyPressed_D() {
press(KeyCode.D);
WaitForAsyncUtils.waitForFxEvents();
assertTrue(pressed);
}
}
代码以运行setup
而不是firestore.rules
,并尝试按照相同的目录结构运行firestore-test.rules
和firebase emulators:start
,但是我的测试失败了jest ./spec
和"should allow delete when user is admin"
失败的原因是通配符中的写入规则。有人知道怎么了吗?
collections.spec.js
"should not allow delete for normal user"
firestore.rules
const { setup, teardown } = require("./helpers");
describe("General Safety Rules", () => {
afterEach(async () => {
await teardown();
});
test("should deny a read to the posts collection", async () => {
const db = await setup();
const postsRef = db.collection("posts");
await expect(postsRef.get()).toDeny();
});
test("should deny a write to users even when logged in", async () => {
const db = await setup({
uid: "danefilled"
});
const usersRef = db.collection("users");
await expect(usersRef.add({ data: "something" })).toDeny();
});
});
describe("Posts Rules", () => {
afterEach(async () => {
await teardown();
});
test("should allow update when user owns post", async () => {
const mockData = {
"posts/id1": {
userId: "danefilled"
},
"posts/id2": {
userId: "not_filledstacks"
}
};
const mockUser = {
uid: "danefilled"
};
const db = await setup(mockUser, mockData);
const postsRef = db.collection("posts");
await expect(
postsRef.doc("id1").update({ updated: "new_value" })
).toAllow();
await expect(postsRef.doc("id2").update({ updated: "new_value" })).toDeny();
});
test("should allow delete when user owns post", async () => {
const mockData = {
"posts/id1": {
userId: "danefilled"
},
"posts/id2": {
userId: "not_filledstacks"
}
};
const mockUser = {
uid: "danefilled"
};
const db = await setup(mockUser, mockData);
const postsRef = db.collection("posts");
await expect(postsRef.doc("id1").delete()).toAllow();
await expect(postsRef.doc("id2").delete()).toDeny();
});
test("should allow delete when user is admin", async () => {
const mockData = {
"users/filledstacks": {
userRole: "Admin"
},
"posts/id1": {
userId: "not_matching1"
},
"posts/id2": {
userId: "not_matching2"
}
};
const mockUser = {
uid: "filledstacks"
};
const db = await setup(mockUser, mockData);
const postsRef = db.collection("posts");
await expect(postsRef.doc("id1").delete()).toAllow();
});
test("should not allow delete for normal user", async () => {
const mockData = {
"users/filledstacks": {
userRole: "User"
},
"posts/id1": {
userId: "not_matching1"
},
"posts/id2": {
userId: "not_matching2"
}
};
const mockUser = {
uid: "filledstacks"
};
const db = await setup(mockUser, mockData);
const postsRef = db.collection("posts");
await expect(postsRef.doc("id1").delete()).toDeny();
});
test("should allow adding a post when logged in", async () => {
const db = await setup({
uid: "userId"
});
const postsRef = db.collection("posts");
await expect(postsRef.add({ title: "new_post" })).toAllow();
});
test("should deny adding a post when not logged in", async () => {
const db = await setup();
const postsRef = db.collection("posts");
await expect(postsRef.add({ title: "new post" })).toDeny();
});
});
来自终端的错误跟踪
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// lock down the db
match /{document=**} {
allow read: if false;
allow write: if false;
}
match /posts/{postId} {
allow update: if userOwnsPost();
allow delete: if userOwnsPost() || userIsAdmin();
allow create: if loggedIn();
}
function loggedIn() {
return request.auth.uid != null;
}
function userIsAdmin() {
return getUserData().userRole == 'Admin';
}
function getUserData() {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data
}
function userOwnsPost() {
return resource.data.userId == request.auth.uid;
}
}
}
答案 0 :(得分:3)
实际上,我遵循相同的教程开始使用Firebase模拟器,并得到了相同类型的错误消息。对我来说,问题是,当您启动模拟器时,它将自动查找您的firestore.rules
文件并加载规则。因此,当您添加mockData
时,规则已经适用。
为了使测试代码正常工作,请将firebase.json
中的Firestore规则文件的设置更改为不存在的文件(或允许所有读/写的规则文件),或者添加{{1 }},以您的mockData
函数的管理员身份,例如:
setup
希望这会有所帮助。
另请参见this question
答案 1 :(得分:0)
对于那些目前在 firestore 8.6.1(或同等版本)中遇到此问题的人,这里讨论了一个错误: https://github.com/firebase/firebase-tools/issues/3258#issuecomment-814402977
修复是降级到 firestore 8.3.1,或者如果您将来阅读本文并且 firestore >= 9.9.0 已经发布,请升级到该版本。