去年我创建了一个Angular / Firebase应用程序,并且开始创建一个类似的应用程序,但是这次使用Firestore,因为我已经阅读了它的“改进版本”(我知道它的工作方式不同,请阅读更多内容)所以What's the difference between Cloud Firestore and the Firebase Realtime Database?)。
看到它仅适用于集合/文档而不适用于字段(触发器和规则)后,我有点不情愿。我一直在寻找带有规则的数据结构的更复杂的示例,但是什么也没看到。
就我而言,我具有这种结构(我从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看起来确实要复杂得多。我开始写东西(错误的atm):
// 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 rules for document field和Firestore update only one field)