当用户首次登录时,我还需要调用一个函数,该函数在我的firestore用户集合中创建一个文档来存储其个人资料数据。使用Web SDK。
(我以前使用的是带有Firebase函数的新的用户触发事件,但它太慢,无法等待冷函数启动)。
安全规则要求
需要确保用户只能在文档ID与他们的用户ID相同的情况下创建文档(以防止用户创建其他文档)。需要确保此文档尚不存在。
尝试-在模拟器中运行,而不是IRL
这些测试通过模拟器,但不通过IRL。
// Allow users to create a doc if the doc ID == their user id
allow create: if path("/databases/" + database + "/documents/users/" + request.auth.uid) == request.path;
OR
allow create: if /databases/$(database)/documents/users/$(request.auth.uid) == request.resource['__name__']
也尝试过此操作(同样,可以在模拟器中使用,但不能在IRL中使用)
match /users/{userId} {
// Allow users to read their own profile
allow create: if request.auth.uid == userId;
}
答案 0 :(得分:1)
所以我想出了一种解决方法。我还具有一些其他写入/更新条件,这些条件阻止用户更改其权限级别。这是由于某种原因,阻止了任何“创造”的发生。因此,我不得不在创建和写入/更新规则中反映相同的条件。由于某些原因,这是必要的。
第一部分,用于创建规则
第二部分-读取,更新,写入
规则
service cloud.firestore {
match /databases/{database}/documents {
// Allow users to create documents in the user's collection
match /users/{document=**} {
allow create: if request.auth.uid != null &&
!("admin" in getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data);
}
// Allow users to read, write, update documents that have the same ID as their user id
match /users/{userId} {
// Allow users to read their own profile (doc id same as user id)
allow read: if request.auth.uid == userId;
// Allow users to write / update their own profile as long as no "admin" field is trying to be added or created
allow write, update: if request.auth.uid == userId &&
!("admin" in getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data);
}
}
}
PS 这一点都不直观,因此,如果有人有更好的解决方法,请发布它。另外,我真的希望firestore 1.0推出后,它将对规则和规则文档带来一些巨大的改进。
答案 1 :(得分:0)
有点晚了,但是我设法调整了一种可能的解决方案并使之生效:
allow create: if path("/databases/(default)/documents/users/" + request.auth.uid) == request.path;
只需将database
变量替换为(default)
。是的,不要幻想...
答案 2 :(得分:0)
我想出了解决方案。我的测试表明,除了自己的uid之外,无法创建其他用户文档,并且它阻止了普通用户更改任何管理员状态。
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function isAdmin() {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).isAdmin == true ||
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true;
}
function signedIn(){
return request.auth.uid != null;
}
match /users/{user} {
// allow updates to own user-doc
allow read, update, delete: if request.auth.uid == user &&
// allow updates to own user-doc if "isAdmin" field is the same as before the update (in case user was already admin)
(request.resource.data.isAdmin == resource.data.isAdmin ||
// or allow updates if "isAdmin" will be set to false
request.resource.data.isAdmin == false ||
// or allow updates if no "isAdmin" field exists after the update
!("isAdmin" in getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data)
);
// allow creation of user-doc with own uid and no others
allow create: if request.auth.uid == user &&
// if no "isAdmin" field is set
!("isAdmin" in getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data);
// give full access to admins
allow read, write: if isAdmin();
}
}
}