В прошлом году я создал приложение Angular / Firebase и начал создавать аналогичное приложение, но на этот раз с помощью Firestore, потому что я читал, что это «улучшенная версия» (я знаю, что она работает по-другому, читайте больше об этом так В чем разница между Cloud Firestore и базой данных Firebase Realtime? ).
Я немного неохотно вижу, что он работает только с коллекциями / документами, а не с полями (триггеры и правила). Я искал более сложный пример структуры данных с правилами, но ничего не увидел.
В моем случае у меня есть эта структура (я взял ее из своего приложения Firebase RDB, но я думаю, что она подходит для Firestore):
users (=collection)
|__ $id (=document)
|__ username
|__ country
|__ language
|__ gender
|__ score
|__ online
|__ ...
Зависит от того, в каком состоянии приложения они являются пользователями, могут обновлять сразу несколько полей (имя пользователя, страна, язык, пол ...) или только одно поле (например, оценка). Они также не могут обновить некоторые поля (например, онлайн).
С правилами RDB я написал это легко:
// USERS
"users": {
// USERS > $UID
"$uid": {
".read": "$uid === auth.uid",
// USERS > $UID > USERNAME
"username":{
".write": "$uid === auth.uid &&
!root.child('usernames/'+newData.val().toUpperCase()).exists() &&
data.val() === ''",
".validate": "newData.isString() && newData.val().matches(/^.{3,15}$/)"
},
// USERS > $UID > COUNTRY
"country": {
".write": "$uid === auth.uid && data.val() === ''",
".validate": "newData.isString() && newData.val().length === 2"
},
// USERS > $UID > LANGUAGE
"language": {
".write": "$uid === auth.uid",
".validate": "newData.isString() && newData.val().length === 2"
},
// USERS > $UID > ONLINE
"online": {
".write": "$uid === auth.uid",
".validate": "newData.isBoolean()"
},
// USERS > $UID > GENDER
"gender": {
".write": "$uid === auth.uid && data.val() === ''",
".validate": "newData.isString() && (newData.val() === '' || newData.val() === 'man'
|| newData.val() === 'woman')"
}
}
}
Но с Firestore это выглядит действительно сложнее. Я начал что-то писать (неправильно):
// USERS > $UID
match /users/{userId} {
allow read: if request.auth.uid == userId;
allow update: if request.auth.uid == userId
// USERS > $UID > USERNAME
&& resource.data.username == ''
&& request.resource.data.username.matches("/^.{3,15}$/")
&& request.resource.data.username is string
&& !exists(/databases/$(database)/documents/usernames/$(request.resource.data))
// USERS > $UID > COUNTRY
&& request.resource.data.country is string
&& request.resource.data.country.size() == 2
&& resource.data.country == ''
// USERS > $UID > LANGUAGE
&& request.resource.data.language is string
&& request.resource.data.language.size() == 2
// USERS > $UID > GENDER
&& resource.data.gender == ''
&& request.resource.data.gender is string
&& request.resource.data.gender in ["man", "woman"];
}
Во-первых, хороша ли моя структура?
Любой хороший пример сложной структуры с правилами?
(Несколько похожих тем: Правила Firestore для поля документа & Обновление Firestore только для одного поля )