gpt4 book ai didi

angular - Firestore : Delete document and security rules

转载 作者:行者123 更新时间:2023-12-03 16:08:32 26 4
gpt4 key购买 nike

描述

我在使用Firestore处理删除时遇到问题。简而言之,我为这样的帖子创建了安全规则:

首先,规则中有一些功能:

服务cloud.firestore {

function userRoles() {
return ['admin', 'customer', 'reader'];
}

function userGenders() {
return ['mal', 'female', 'other'];
}

function postVisibilities() {
return ['public', 'private', 'protected'];
}

function postType() {
return ['music', 'motion_design', 'graphic_art'];
}

function isPayment(paymentDoc) {
return paymentDoc != null
&& paymentDoc.date is timestamp
&& paymentDoc.price is number
&& paymentDoc.price is number
&& paymentDoc.price > 0;
}

function isBill(billDoc) {
return billDoc.sellerId is string
&& billDoc.buyerId is string
&& billDoc.postIds != null
&& billDoc.date is timestamp
&& billDoc.paymentDoc != null
&& isPayment(billDoc.paymentDoc);
}

function isAccount(accountDoc) {
return accountDoc.isRegistered is bool
&& accountDoc.addressId is string
&& accountDoc.contactId is string
&& accountDoc.email is string
&& accountDoc.username is string
&& accountDoc.gender is string
&& accountDoc.gender in userGenders()
&& accountDoc.role is string
&& accountDoc.role in userRoles();
}

function isPost(postDoc) {
return postDoc.createdAt is timestamp
&& postDoc.updatedAt is timestamp
&& postDoc.title is string
&& postDoc.text is string
&& postDoc.image is string
&& postDoc.authorId is string
&& postDoc.visibility is string
&& postDoc.visibility in postVisibilities();
}

function isVote(voteDoc) {
return voteDoc.authorId is string
&& voteDoc.reaction is string
&& voteDoc.reaction in ['up', 'down'];
}

function isComment(commentDoc) {
return commentDoc.authorId is string
&& commentDoc.message is string;
}

function isSingle(doc) {
return doc.size() == 1;
}

match /databases/{database}/documents {

function userExists(userId) {
return userId != null && exists(/databases/$(database)/documents/accounts/$(userId));
}

function getUserRole(userId) {
return get(/databases/$(database)/documents/accounts/$(userId)).data.roles;
}

function hatUserRole(userId, role) {
return getRoleForUser(userId) in role;
}

match /{document=**} {
allow read: if true;
allow write: if false;
}

match /accounts/{accountId} {

allow create: if isAccount(request.resource.data)
&& (request.auth.uid == accountId || hatUserRole(request.auth.uid, ['admin']));
allow update: if request.auth.uid == accountId || hatUserRole(request.auth.uid, ['admin']);
allow delete: if hatUserRole(request.auth.uid, ['admin']);

match /contacts/{contactId} {
allow write: if isSingle(request.resource.data)
&& request.auth.uid == accountId;
allow read: if userExists(request.auth.uid);
}

match /favorites/{favoriteId} {
allow write: if isSingle(request.resource.data)
&& request.auth.uid == accountId;
allow read: if userExists(request.auth.uid);
}

match /votes/{voteId} {

allow create: if isVote(request.resource.data)
&& userExists(request.auth.uid);
allow update: if userExists(request.auth.uid)
&& isVote(request.resource.data)
&& request.resource.data.authorId == request.auth.uid
allow delete: if userExists(request.auth.uid)
&& (request.auth.uid == accountId
|| hatUserRole(request.auth.uid, ['admin']))
}
}

match /bills/{billId} {
allow create: if isBill(request.resource.data)
&& userExists(request.resource.data.sellerId)
&& userExists(request.resource.data.buyerId)
&& (request.resource.data.buyerId == request.auth.uid
|| request.resource.data.sellerId == request.auth.uid);
allow update, delete: if false;
allow read: if request.resource.data.buyerId == request.aut.uid
|| request.resource.data.sellerId == request.aut.uid;
}

match /posts/{postId} {

function publicPost() {
return get(/databases/$(database)/documents/posts/$(postId)).data.visibility == 'public';
}

function postVisibility() {
return get(/databases/$(database)/documents/posts/$(postId)).data.visibility;
}

function protectedPost() {
return userExists(request.auth.uid)
&& get(/databases/$(database)/documents/posts/$(postId)).data.visibility == 'public';
}

function findPostAuthor(pathToFind) {
return get(/databases/$(database)/documents/posts/$(pathToFind)).data.authorId
}

allow create, update: if isPost(request.resource.data)
&& userExists(request.auth.uid)
&& request.resource.data.authorId == request.auth.uid;
allow read: if request.resource.data.visibility == 'public';
allow delete: if userExists(request.auth.uid)
&& findPostAuthor(request.resource.id) == request.auth.uid;

match /votes/{voteId} {
allow read: if protectedPost(postId)
|| publicPost(postId);
allow create: if isVote(request.resource.data)
&& postVisibility(postId) in ['public', 'protected']
&& userExists(request.auth.uid);
allow update: if isVote(request.resource.data)
&& request.resource.data.authorId == request.auth.uid;
allow delete: if userExists(request.auth.uid)
&& (request.auth.uid == request.resource.data.authorId
|| hatUserRole(request.auth.uid, ['admin']));
}

match /comments/{commentId} {
allow read: if protectedPost(postId) || publicPost(postId);
allow create: if isComment(request.resource.data)
&& postVisibility(postId) in ['public', 'protected']
&& userExists(request.auth.uid);
allow update: if isComment(request.resource.data)
&& request.resource.data.authorId == request.auth.uid;
allow delete: if userExists(request.auth.uid)
&& (request.auth.uid == request.resource.data.authorId
|| hatUserRole(request.auth.uid, ['admin']));
}
}
}
}

对于创建和更新,一切正常。

之后,我创建了两个方法实现来删除文档,其中两个使用 id:
public deletePost(postId: string): Observable<void> {
const postRef = this.db.collection('posts').doc(postId).ref;

return fromPromise(this.db.firestore.runTransaction((transaction => {
return transaction.get(postRef).then(snapshot => {
if (!snapshot.exists) {
this.snackBar.open('Post doesn\'t exist', 'close');
} else {
const auth = snapshot.data().authorId === this._userId;
if (auth) {
transaction.delete(postRef);
} else {
this.snackBar.open('You\' not allowed to do that!');
}
}
});
})));
}

使用交易,以及:
protected removeElement(elementId: string): Observable<any> {
return fromPromise(this.db.collection(this.dbCollection).doc(elementId).delete());
}

不使用任何交易,简单删除。

问题

这些方法都不起作用。

使用第一种方法时,我得到:
ERROR Error: Server responded with status 
at new FirestoreError (index.cjs.js:346)
at T.<anonymous> (index.cjs.js:6901)
at Ab (index.js:23)
at T.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.dispatchEvent (index.js:21)
at te (index.js:66)
at ve (index.js:69)
at T.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.jb (index.js:67)
at T.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.Na (index.js:67)
at XMLHttpRequest.wrapFn (zone.js:1188)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:3815)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:496)
at invokeTask (zone.js:1540)
at XMLHttpRequest.globalZoneAwareCallback (zone.js:1566)

我得到第二个:
ERROR Error: Missing or insufficient permissions.
at new FirestoreError (index.cjs.js:346)
at index.cjs.js:7088
at W.<anonymous> (index.cjs.js:7033)
at Ab (index.js:23)
at W.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.dispatchEvent (index.js:21)
at Re.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.Re.Ca (index.js:98)
at ye.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.Oa (index.js:86)
at dd (index.js:42)
at ed (index.js:39)
at ad (index.js:37)
at L.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.Sa (index.js:36)
at L.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.nb (index.js:35)
at Ab (index.js:23)
at T.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.dispatchEvent (index.js:21)
at ve (index.js:68)
at T.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.jb (index.js:67)
at T.push../node_modules/@firebase/webchannel-wrapper/dist/index.js.g.Na (index.js:67)
at XMLHttpRequest.wrapFn (zone.js:1188)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:3815)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:496)
at invokeTask (zone.js:1540)
at XMLHttpRequest.globalZoneAwareCallback (zone.js:1566)

因为我不确定问题出在哪里,所以我有一些理论:
  • 也许在rules中,当我写的时候
    allow delete: if userExists(request.auth.uid) && findPostAuthor(request.resource.data.id) == request.auth.uid;
    我认为,因为我只使用Id直接查看文档,所以request.resource.data.id不得包含任何内容。
  • 我还认为,如果transactions不起作用,可能是因为它的实际工作方式与我们在其他事务功能上看到的方式确实不同。

  • 当我使用 angularFire2时,this.db => AngularFirestore,this.dbCollection =>'posts',在任何帖子的结构中,都有一个 autorId字段,它是一个字符串。

    最佳答案

    对于delete,您需要将request.auth.uidresource.data.uid而不是request.resource.data.uid进行比较。例如:

    match /bookmarks/{id} {
    allow create: if request.resource.data.uid == request.auth.uid
    allow read, delete: if resource.data.uid == request.auth.uid
    }

    关于angular - Firestore : Delete document and security rules,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52024666/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com