LoginSignup
1
0

More than 3 years have passed since last update.

firestoreで更新するドキュメントがあればバリデーションをかける

Posted at

単純にnullチェックをするだけでは微妙なことになる。
ハマったので議事録的に残す。

firestoreのrulesにはコメントも書き込める。
RDBみたいにちょっと繋げば制約とデータ構造を把握できるが、firestoreだとおそらくこれを見るしかないので該当のカラムに対してvalidationメソッドを明示的に用意するといいかも。

Realtime Databaseでは .validate が用意されており、明示的に書くことができた。
firestoreではまだこういった仕組みは用意されてないように見え、自信でvalidationを実装する必要がある。
https://firebase.google.com/docs/database/security?hl=ja#section-validation

うーん、可読性が低いのでなんとかしてほしいなー
いい方法があるんだろうか


service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userID} {
      allow read: if true;
      allow create, update: if request.auth != null 
                              && request.auth.uid == userID
                              && isValidUsers();
    }

    // utilitie functions

    function existingData() {
      return resource.data
    }

    function incomingData() {
      return request.resource.data
    }

    function currentUser() {
      return request.auth
    }

    // collection rules

    function isValidUsers() {
      return isValidNickName() 
              && isValidProfileText()
              && isValidIconURL()
              && isValidCreatedAt()
              && isValidUpdatedAt()
    }

    // document rules

    function isValidNickName(){
      return (incomingData().keys().hasAll(['nickname']) == false || 
      (incomingData().nickname != null 
        && incomingData().nickname is string
        && incomingData().nickname.size() > 0 
        && incomingData().nickname.size() <= 20))
    }

    function isValidProfileText(){
      return (incomingData().keys().hasAll(['profile_text']) == false || 
      (incomingData().profile_text != null 
        && incomingData().profile_text is string
        && incomingData().profile_text.size() >= 0 
        && incomingData().profile_text.size() <= 500))
    }

    function isValidIconURL(){
      return incomingData().keys().hasAll(['icon_url']) == false || 
      (incomingData().icon_url != null && incomingData().icon_url is string)
    }

    function isValidCreatedAt(){
      return incomingData().keys().hasAll(['created_at']) == false || 
      (incomingData().created_at != null && incomingData().created_at is timestamp)
    }

    function isValidUpdatedAt(){
      return incomingData().keys().hasAll(['updated_at']) == false || 
      (incomingData().updated_at != null && incomingData().updated_at is timestamp)
    }
  }
}
1
0
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
0