Firebase模拟器上的Firebase权限被拒绝错误

时间:2020-05-24 10:24:29

标签: javascript firebase google-cloud-firestore jestjs firebase-security

我正在将此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.rulesfirebase 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;
    }
  }
}

2 个答案:

答案 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 已经发布,请升级到该版本。