Help us understand the problem. What is going on with this article?

もう間違えない! Cloud Firestore rulesのresource, request.resource, writeFields

More than 1 year has passed since last update.

Cloud Firestoreのrulsを書く上でややこしい

  • resource 変数
  • request.resource 変数
  • writeFields 変数

のそれぞれの違いを説明しようと思います。これを見ればもう間違えることはなくなるはず。

TL;DR

  • resource: 現在DBに格納されているドキュメント
  • request.resource: 書き込みを行った場合に期待される将来のドキュメント(の状態)
  • writeFields: 書き込みを行う場合に、書き込もうとしているフィールドのkeyの一覧

それぞれの違い

resource

ドキュメントによると、

resource 変数は要求されたドキュメントを参照し、resource.data はドキュメントに格納されているすべてのフィールドと値のマップです。

とあるので、現在のドキュメントに格納されているフィールドと値のmapを参照できます。
rulesのそれぞれのオペレーションでは以下の通り。

  • read(get, list): 現在のDBに格納されているドキュメント
  • create: undefined
  • update: 現在のDBに格納されているドキュメント
  • delete: 現在のDBに格納されているドキュメント

request.resource

ルールセットが保留中の書き込みを許可する場合は、request.resource 変数にはドキュメントの将来の状態が含められます。ドキュメント フィールドのサブセットのみを変更する update オペレーションの場合、request.resource 変数にはオペレーション後の保留中のドキュメントの状態が含まれます。

つまり、書き込みのオペレーション(crate, update, delete)を実行した後の(保留)ドキュメント状態がmapとして格納される。なので

  • read(get, list): undefined(writeオペレーション時のみ存在するため)
  • create: 新規で書き込むドキュメントのフィールドと値のmap
  • update: 値の追加更新削除をした後の 将来の状態の フィールドと値のmap。
  • delete: undefined

となる。 update の場合は、追加更新削除後の 将来の状態 を表すので、あるオペレーションで既存のデータ {A, B}{C} を書き加えて更新する場合、 request.resource.data には {A, B, C} が含まれる。
一方で

writeFields

List of fields being written in a write request.

とあり、意訳すると、「書き込みリクエスト時に書き込まれるであろうフィールドのリスト」となる。

  • read(get, list): undefined
  • create: 書き込むフィールドのkey (request.resource.data.keys() と一致)
  • update: 今回更新追加削除するフィールドのkey (request.resource.data.keys()必ずしも一致しない 。update時に変更しようとしているフィールドのkeyのみ)
  • delete: undefined

表にしてみる

実際にそれぞれのオペレーションで、現在のフィールド、書き込むフィールドが与えられた時に、resource, request.resourcet, writeFields の値がどう変化するか表にまとめます。

read(get, list)

現在のフィールド 書き込むフィールド resource request.resource writeFields
{
  name: 'mike',
  age: 25
}
undefined {
  name: 'mike',
  age: 25
}
undefined undefined

create

現在のフィールド 書き込むフィールド resource request.resource writeFields
undefined {
  name: 'mike',
  age: 25
}
undefined {
  name: 'mike',
  age: 25
}
['name', 'age']

update

現在のフィールド 書き込むフィールド resource request.resource writeFields
{
  name: 'mike',
  age: 25
}
{
  company: 'Foobar Inc.'
}
{
  name: 'mike',
  age: 25
}
{
  name: 'mike',
  age: 25,
  company: 'Foobar Inc.'
}
['company']

delete

現在のフィールド 書き込むフィールド resource request.resource writeFields
{
  name: 'mike',
  age: 25
}
undefined {
  name: 'mike',
  age: 25
}
undefined undefined

参考

sgr-ksmt
Software Engineer. Skill: iOS / Swift / Firebase / TypeScript / React
https://me.sgr-ksmt.org/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした