用户只能在Firestore上读取/写入自己的提交



我对Firestore规则迷失了方向。

我希望经过身份验证的用户能够读取自己的提交,但我仍然收到的权限不足。我正在将用户 ID 写入每个提交中。

// add submit to submits collection in firestore
db.collection('submits').add({
user: this.user,
number: this.number,
timestamp: moment.utc(this.timestamp).format(),
usage: this.usage
})

在这里,我检查哪个用户已登录并获取其提交的用户

let ref = db.collection('users')
// get current user
ref.where('user_id', '==', firebase.auth().currentUser.uid).get()
.then(snapshot => {
snapshot.forEach(doc => {
this.user = doc.data()
this.user = doc.data().user_id
})
})
.then(() => {
// fetch the user previous submits from the firestore
db.collection('submits').where('user', '==', this.user).get()
.then(snapshot => {
// console.log(snapshot)
snapshot.forEach(doc => {
let submit = doc.data()
submit.id = doc.id
submit.timestamp = moment(doc.data().timestamp).format('lll')
this.previousSubmits.push(submit)
})
})
})
}

这些是我的消防店规则

service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches name of the user
// document. The wildcard expression {userId} makes the userId variable
// available in rules.
match /users/{userId} {
allow read, update, delete: if request.auth.uid == userId;
allow create: if request.auth.uid != null;
}
// check if the user is owner of submits he is requesting
match /submits/{document=**} {
allow read: if resource.data.user == request.auth.uid;
allow write: if request.auth.uid != null;    
}

}
}

有人知道我做错了什么吗?

更新,添加了我用于在 users 集合中创建用户文档的代码:

signup () {
if (this.alias && this.email && this.password) {
this.slug = slugify(this.alias, {
replacement: '-',
remove: /[$*_+~.()'"!-:@]/g,
lower: true
})
let ref = db.collection('users').doc(this.slug)
ref.get().then(doc => {
if (doc.exists) {
this.feedback = 'This alias already exists'
} else {
firebase.auth().createUserWithEmailAndPassword(this.email, this.password)
.then(cred => {
ref.set({
alias: this.alias,
household: this.household,
user_id: cred.user.uid
})
}).then(() => {
this.$router.push({ name: 'Dashboard' })
})
.catch(err => {
console.log(err)
this.feedback = err.message
})
this.feedback = 'This alias is free to use'
}
})
}
}

部分问题在于您尝试搜索user_id字段等于用户 ID 的文档,但您的安全规则说,"仅当文档的 ID 与用户的 ID 相同时,才允许用户阅读文档",这是完全不相关的,我不知道在您的情况下是否真的如此。

一种选择是更改您的规则,您说:"嘿,如果user_id字段的值等于您的用户 ID,您可以读取/更改文档,这将是这样的......

match /users/{userId} {
allow read, update, delete: if request.auth.uid == resource.data.user_id;
// ...
}

。或者更改查询,以便查询其 ID 是当前用户的 UID 的特定文档。

let ref = db.collection('users').document(currentUser.uid)
ref.get() {... }

但是,我想,不要同时做这两件事。 :)

错误来自您尝试获取当前用户的第一行:

ref.where('user_id', '==', firebase.auth().currentUser.uid).get()

此行选择user_id字段与当前用户 ID 匹配的文档,但您的 Firestore 规则正在检查用户的 ID 是否与文档的ID 匹配。由于您正在生成带有slugify的文档 ID,因此它不匹配,这会导致权限错误。

Todd 对规则更改的建议将起作用,但最好只使用用户 ID 作为文档 ID,并将用户的 slug 存储为字段。这样你就不必担心冲突(用户 ID 将自动是唯一的(,也不必使用 select 语句 - 您将知道每个用户只有一个文档,并且可以直接访问它:

ref.doc(firebase.auth().currentUser.uid).get()

作为旁注,您实际上似乎没有任何理由在这一点上检索用户文档(至少在您的示例代码中(。如果您实际上只是使用它来获取user_id字段,则可以跳过它,因为您已经拥有auth会话中的用户 ID。在这种情况下,您应该这样做:

this.user = firebase.auth().currentUser.uid
db.collection('submits').where('user', '==', this.user).get()
.then(snapshot => {
// console.log(snapshot)
snapshot.forEach(doc => {
let submit = doc.data()
submit.id = doc.id
submit.timestamp = moment(doc.data().timestamp).format('lll')
this.previousSubmits.push(submit)
})
})

最新更新