Firestore セキュリティルールで使える関数一覧

Firestoreのセキュリティルールを使うと値の様々なバリデーションができますよね。
ただ 個人で利用する際は`size()`とか`matches()`などしか使っていませんでした。
そこで、どんな関数があるのか調べてまとめてみました。

以下記載の関数は、セキュリティルールの`request.resource.data.プロパティ名`の型に合わせて、判定時のデータ整形、判定自体に使えます。

（以下例）

```js

  function isValidUserData(user) {
    return 1 <= user.name.size() && user.name.size() <= 30 // nameは1文字以上30文字以内であること
      && user.gender.matches('male|female|genderDiverse') // `gender`は`male`, `female`, `genderDiverse`の３種類だけが選べる
      && 0 <= user.age && user.age <= 150 // `age`は0〜150の数値である
  }

  match /databases/{database}/documents {
    match /users/{userId} {
      allow read:  if true;
      allow create: if isValidUserData(request.resource.data);
    }
  }
```

# String型の関数

## [Lower](https://firebase.google.com/docs/reference/rules/rules.String#lower)
文字列をLowerケースにする

```js
'ABC'.lower() // 'abc'
```

## [upper](https://firebase.google.com/docs/reference/rules/rules.String#upper)
文字列をUpperケースにする

```js
'abc'.upper() // 'ABC'
```

## [matches](https://firebase.google.com/docs/reference/rules/rules.String#matches)
引数に渡した正規表現で、文字列を判定した結果を返す

```js
'user@domain.com'.matches('.*@domain[.]com') // true
```
## [size](https://firebase.google.com/docs/reference/rules/rules.String#size)
文字数を返す

```js
'abc'.size() // 3
```

## [split](https://firebase.google.com/docs/reference/rules/rules.String#split)
引数に渡したデリミタで文字列を分割して、配列を返す

```js
'a/b/c'.split('/') // ['a', 'b', 'c']
```

## [trim](https://firebase.google.com/docs/reference/rules/rules.String#trim)
前後の空白を削除した文字列を返す

```js
'  a  '.trim() // 'a'
```

# List型の関数

## [hasAll](https://firebase.google.com/docs/reference/rules/rules.List#hasAll)
配列内に引数に渡した配列のすべての要素が含まれているかどうかを判定する

```js
['りんご', 'なし', 'ぶどう'].hasAll(['なし', 'りんご']) // true
['りんご', 'なし', 'ぶどう'].hasAll(['ばなな', 'ぶどう']) // false
```

## [hasAny](https://firebase.google.com/docs/reference/rules/rules.List#hasAny)
配列の要素が、引数に渡した配列に含まれているかどうかを判定する

```js
['りんご', 'なし', 'ぶどう'].hasAny(['なし', 'りんご']) // true
['りんご', 'なし', 'ぶどう'].hasAny(['ばなな']) // false
```

## [hasOnly](https://firebase.google.com/docs/reference/rules/rules.List#hasOnly)
配列内のすべての要素が、引数に渡した配列に存在するか判定する

```js
['a', 'b'].hasOnly(['a', 'c'])// false
['a', 'b'].hasOnly(['a', 'b', 'c'])// true
```

## [join](https://firebase.google.com/docs/reference/rules/rules.List#join)
配列の要素を結合し文字列で返す

```js
['a', 'b'].join() // 'ab'
```

## [size](https://firebase.google.com/docs/reference/rules/rules.List#size)
配列の要素数を数値で返す

```js
['a', 'b'].size() // 2
```

# Map型の関数

## [keys](https://firebase.google.com/docs/reference/rules/rules.Map#keys)
マップのキーの配列を返す

```js
{ 'name': '太郎', 'address': '茨城県' }.keys() // ['name', 'address']
```

## [values](https://firebase.google.com/docs/reference/rules/rules.Map#values)
マップの値の配列を返す

```js
{ 'name': '太郎', 'address': '茨城県' }.values() // ['太郎', '茨城県']
```

## [size](https://firebase.google.com/docs/reference/rules/rules.Map#size)
マップの要素数を数値で返す

```js
{ 'name': '太郎', 'address': '茨城県' }.size() // ['name', 'address'] // 2
```

# Timestamp型の関数

## [year](https://firebase.google.com/docs/reference/rules/rules.Timestamp#year), [month](https://firebase.google.com/docs/reference/rules/rules.Timestamp#month), [day](https://firebase.google.com/docs/reference/rules/rules.Timestamp#day), [hours](https://firebase.google.com/docs/reference/rules/rules.Timestamp#hour), [minutes] (https://firebase.google.com/docs/reference/rules/rules.Timestamp#minute), [seconds](https://firebase.google.com/docs/reference/rules/rules.Timestamp#seconds)

Timestampの指定要素で数値として返す

```js
"1989-12-31T11:22:33Z".year() // 1989
"1989-12-31T11:22:33Z".month() // 12
"1989-12-31T11:22:33Z".day() // 31
"1989-12-31T11:22:33Z".hours() // 11
"1989-12-31T11:22:33Z".minutes() // 22
"1989-12-31T11:22:33Z".seconds() // 33
```

## [dayOfWeek](https://firebase.google.com/docs/reference/rules/rules.Timestamp#dayOfWeek)
曜日を1〜7の数値で返す

```js
"2019-09-21T11:22:33Z".dayOfWeek() // 1 （日曜日）
```

## [dayOfYear](https://firebase.google.com/docs/reference/rules/rules.Timestamp#dayOfWeek)
一年を1〜366の数値とした場合の値を数値として返す

```js
"2019-12-31T11:22:33Z".dayOfYear() // 366
```

# 終わりに
以上 Firestore セキュリティルールで使える関数一覧でした。
ここで上げた意外にも、様々な型、関数が用意されています。
それぞれの関数を使う具体的なユースケースはまだ思い浮かばないのですが、
今後の個人開発に活かしていきたいです。