Firestore 安全规则中嵌套映射中的引用字段

时间:2021-02-02 14:24:05

标签: firebase google-cloud-firestore firebase-security

我有这个数据结构:

enter image description here

并且需要一个规则,仅当 city 属性未更改时才允许更新:

match /requests/{requestId} {
  allow update: if (request.resource.data.diff(resource.data).unchangedKeys().
     hasAll(["customerlocation.city"]))

这不起作用,因为 diff 结果只显示 customerlocation 字段,而不显示 city 属性。

甚至有可能实现我想要的吗?我知道在安全规则中使用嵌套对象有一些限制,但我可能只是遗漏了一些东西。

3 个答案:

答案 0 :(得分:2)

如果您不想更改数据结构并且必须在 Firestore 规则内执行此操作,我相信 Aion 提出的解决方案是唯一可行的解​​决方案。

我不知道您的整体数据结构是什么样的,但您可以将 customerLocation 移到它自己的集合中。然后,您将在 customerLocation 内存储对 request 的 DocumentReference。

您还可以使用 document('requests/{requestId}').onUpdate() 创建一个云函数并检查城市是否发生了变化。如果有,那么把它改回那里。这将要求您跟踪您更改回属性的事实。否则,该函数将继续触发和翻转值。

答案 1 :(得分:0)

为什么不直接比较字段值?

APP_NAME=Laravel
APP_ENV=production
APP_KEY=base64:hkzyStjgzyyDQk7DjIK0nXHOIUQ/5mUYcM0fQP6hCnE=
APP_DEBUG=false
APP_URL=http://35.184.16.20

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=db_username
DB_PASSWORD=db_password

BROADCAST_DRIVER=pusher
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=myid
PUSHER_APP_KEY=somekey
PUSHER_APP_SECRET=somesecret
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

答案 2 :(得分:0)

我只是建议您检查一下 City 是否仍处于默认值,在此示例中,我将其设置为“默认城市”(该默认值可能为零)

match /requests/{requestID} {
  allow update: if request.resource.customerLocation.city == "Default City"
}

由于未引用您的整个 Firestore 数据库,因此在您的项目中可能看起来略有不同,但我认为这在逻辑上是可行的。