Firestoreのruleを記述する時に、documentのfieldがnullなのかundefinedを判定する方法を。

nullundefinedの違い

指定したfieldがnullであるかundefinedであるかの違いは

  • null: fieldのkeyがあって、valueがnullである
  • undefined: field自体が存在しない

となる。例を出すと


2つの画像で、nameのfieldに着目すると、
1枚目はnullであり、2枚目はundefinedとなる。


これを踏まえて、ruleでの判定の方法を。

nullであるかどうか

nullの判定は == nullで判定できます

// profileフィールドがnullでないあることを期待
allow create: if request.resource.data.profile == null;
// nameフィールドがnullでないことを期待
allow create: if request.resource.data.name != null;

undefinedであるかどうか

undefinedであるかの判定は、実は == undefined では判定できない。

// nameフィールドがundefinedであるかを判定(これは間違い)
allow create: if request.resource.data.name == undefined;

なのでひと工夫が必要となる。
request.resource.dataもしくはresource.dataはMap型の変数なので、一度Mapからkeyだけの配列を取り出し、
その中に対象となるfield名が 含まれない かをチェックする。

// nameフィールドがundefinedであるかを判定
allow create: if !request.resource.data.keys().hasAll(['name']);

これで、document.nameがundefinedか判定ができる。
このままだと若干使いづらいので、次のように関数化して使えるようにすると良い。

function isUndefined(data, field) {
  return !data.keys().hasAll([field]);
}

allow create: if isUndefined(request.resource.data, 'name');