Javaエンジニア、React+Firebaseでアプリを作る

趣味で作ったものいろいろ

FirestoreでEnum型風ルールを作成する

Firestoreではセキュリティルールでフィールドの型を指定できます。 フィールドの型にはboolintstringなどがあります。 しかしenum型は存在しません。

Firebaseのセキュリティルールでは、string型のフィールドに対して登録できる文字列を制限することができます。 この機能を使うことでenum型風のフィールドを作成することができます。

String.matches(regex)

String.matchesを使うと、フィールドに登録される値が 指定された正規表現を満たす場合にのみ、DBに登録することができます。 記述はこのようになります。

allow create, update: if request.resource.data.status.matches("^(TODO|IN_PROGRESS|DONE)$")

String.matches(regex)の使用例

例としてTODOアプリを考えます。入力はタスク名とステータス(実施状況)です。

f:id:yucatio:20211017171414p:plain:w300

データ構造はこのようになっています。

f:id:yucatio:20211017230600p:plain:w350

status(ステータス)には"TODO"(未着手)か"IN_PROGRESS"(作業中)か"DONE"(完了)のみ指定できます。

これをセキュリティルールで書くとこのようになります。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /todos/{todo} {
      function validTodo(docData) {
        return docData.status.matches("^(TODO|IN_PROGRESS|DONE)$")
      }
      
      allow read: if true;
      allow create, update: if validTodo(request.resource.data);
    }
  }
}

このセキュリティルールでステータスが"TODO"のタスクを登録します。 Firebaseのコンソールで確認すると登録されていることが分かります。

f:id:yucatio:20211017172045p:plain

もし"IN_PROGRESS"を"DOING"と間違えてしまった場合、"Missing or insufficient permissions."のエラーが出ます。DBを確認すると登録ができていないことが確認できます。

f:id:yucatio:20211017172609p:plain
google chromeのコンソール

最後に、念のため正規表現があっているか確かめておきましょう。

https://jex.im/regulex/#!flags=&re=%5E(TODO%7CIN_PROGRESS%7CDONE)%24

f:id:yucatio:20211017171755p:plain

大丈夫そうですね。