LoginSignup
1
1

More than 1 year has passed since last update.

実録!Firebaseのセキュリティルールをテストをしていたときに遭遇したエラーを解決!

Posted at

はじめに

@firebase/rules-unit-testingを使って、セキュリティルールをテストするためのコードを書いていました。

その時に書いていたコードの内容は次の内容です。

import "jest";
import * as fs from "fs";
import {
  initializeTestEnvironment,
  RulesTestContext,
  RulesTestEnvironment,
} from "@firebase/rules-unit-testing";
import {
  doc,
} from "firebase/firestore";
import { v4 as uuidv4 } from "uuid";


describe("テスト /users", () => {
  let testEnv: RulesTestEnvironment;
  let user: RulesTestContext;
  const projectId = uuidv4();
  const uid = uuidv4();
  beforeAll(async () => {
    testEnv = await initializeTestEnvironment({
      projectId: projectId,
      firestore: {
        rules: fs.readFileSync("../firestore.rules", "utf8"),
      },
    });
    user = testEnv.authenticatedContext(uid, {});
    // ...
  });

  afterAll(async () => {
    testEnv.cleanup();
  });

  it("テスト1", async () => {
    const ref = doc(user.firestore(), "users", uid);
    // ...
  });
  it("テスト2", async () => {
    const ref = doc(user.firestore(), "users", uid);
    // ...
  });
});

テストを実行してみると、2番目に実行されたテストが失敗していました。

テスト /users
    ✓ テスト1 (97 ms)
    ✕ テスト2 (129 ms)

しかし、テスト2のみを実行してみるとテストは通りました。

エラーの内容

発生したエラーの内容は次の内容です。

FirebaseError: Firestore has already been started and its settings can no longer be changed. You can only modify settings before calling any other methods on a Firestore object.

エラーの原因

色々試していくと、上記のエラーが発生した原因は次のコードにあることがわかりました。

  let user: RulesTestContext;
  const uid = uuidv4();
  // ...
  beforeAll(async () => {
    // ...
    user = testEnv.authenticatedContext(uid, {});
    // ...
  });

  it("テスト1", async () => {
    const ref = doc(user.firestore(), "users", uid);
    // ...
  });
  it("テスト2", async () => {
    const ref = doc(user.firestore(), "users", uid);
    // ...
  });

共通のRulesTestContextをテストケースごとに使い回して、user.firestore()をその度に呼び出していたことが上記のエラーが発生した原因であることが判明しました。

解決方法

そこで、authenticatedContext()の呼び出しをテストケースごとに行い、使い回しをやめることにしました。

it("テスト1", async () => {
  const user = testEnv.authenticatedContext(uid, {});
  const ref = doc(user.firestore(), "users", uid);
  // ...
});
it("テスト2", async () => {
  const user = testEnv.authenticatedContext(uid, {});
  const ref = doc(user.firestore(), "users", uid);
  // ...
});

結果、以前のコードで発生していたエラーは解消されました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1