firebase.json に複数の Storage を設定していると Emulator がエラーになる事象の対応

firebase.json に複数の Storage を設定していると Emulator がエラーになる事象の対応

January 13, 2022

例えばあなたの Firebase プロジェクトに、画像を格納するバケットと、動画を格納するバケットがあるとした場合、各設定ファイルは以下のようになるはずです。

firebaserc

{
  "projects": {
    "default": "example-project"
  },
  "targets": {
    "example-project": {
      "storage": {
        "images": ["example-project-images"],
        "videos": ["example-project-videos"]
      }
    }
  }
}

firebase.json

{
  "storage": [
    {
      "target": "images",
      "rules": "storage.images.rules"
    },
    {
      "target": "videos",
      "rules": "storage.videos.rules"
    }
  ]
}

storage.images.rules

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write;
    }
  }
}

storage.videos.rules

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

上記で Firebase CLI のデプロイコマンドを実行すれば、それぞれのバケットのルールも更新されます。

firebase.json で複数バケットを指定した状態でエミュレータを起動するとエラーになる #

デプロイはちゃんとできました。しかしながら上記設定ファイルの状態でエミュレータを起動すると以下のエラーになるはずです。

Error: Cannot start the Storage emulator without rules file specified in firebase.json: run 'firebase init' and set up your Storage configuration

どうやら firebase.json"storage" のフィールドを配列で指定しているとエミュレータは読み取れないようです。

実際に以下のように修正すればエミュレータは問題なく起動するようになります。

firebase.json

{
  "storage": {
    "target": "images",
    "rules": "storage.images.rules"
  }
}

Issue があげられているものの現在対応されておらず #

Firebase のリポジトリにも同様の Issue があげられていますが記事作成時点ではまだ Fix されていません。

対処方法 #

いくつかのワークアラウンドが上記 Issue 内で記載されていますが、簡易的な対応でよければ以下でよいのではないでしょうか。

  • ルールをデプロイするときは先の設定状態にしてからデプロイを実行する。
  • エミュレータ環境での開発中は firebase.json の設定を変え、エミュレータ用の1ファイルだけを読み込ませる。

エミュレータ環境での開発中について、具体的には以下のようにします。

{
  "storage": {
    "target": "default",
    "rules": "storage.emulator.rules"
  }
}

storage.emulator.rules

rules_version = '2';
service firebase.storage {

  match /b/example-project-images/o {
    match /{uid}/{allPaths=**} {
      allow read, write;
    }
  }

  match /b/example-project-videos/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }

}

Storage のルールを更新する頻度はそこまで高くないでしょうし、バグが解消されるまでの間はこの対処方法で十分ではないでしょうか。