Firebase安全规则-访问其他文档中的字段



简介

我的数据库上有这个结构

C- usernames
D- paola
-> userId: 7384-aaL732-8923dsnio92202-peesK
D- alex
-> userId: ...
D- adam
-> userId: ...

C- users
D- userId of paola
-> username: "paola"
-> ...
D- userId of alex
-> username: "alex"
-> ...
D- userId of adam
-> username: "adam"
-> ...

我正在客户端注册用户,所以我必须编写一些安全规则。。。

在我的客户端代码中我做:

  1. 将用户名(文档id(和userId(文档数据(添加到用户名集合
  2. 在users集合中创建一个包含用户名和其他内容的用户文档

安全规则

所以,我的安全规则是这样的:

function isUsernameOwner(username) {
return get(/databases/$(database)/documents/usernames/$(username)).data.userId == request.auth.uid;
}
match /users/{userId} {
// Every people can read the users collection (might be in the sign in form)
allow read: if true;

// As the users creation is made in the client side, we have to make sure
// it meets these requirements
allow write: if isSignedIn() &&
isSameUser(userId) &&
request.resource.data.keys().hasOnly(['email', 'username', 'name', 'birthday']) &&
isValidUsername(request.resource.data.username) &&
isUsernameOwner(request.resource.data.username); // <------- If I remove this all works fine
}

问题

当我尝试注册时,我会得到";缺少或权限不足";。。。我认为问题出在函数isUsernameOwner((上,但我不知道我做错了什么。。。我是否错误地访问了用户名文档中的字段userId?如果不是,是否有可能批处理写入不按顺序进行?

Pd:注册过程使用批量写入(首先写入用户名,然后写入用户(

更新

这是我进行批量写入的javascript代码:

// Firebase.js
createUser = (email, password, username, name, birthday) => {
return this.auth
.createUserWithEmailAndPassword(email, password)
.then((currentUser) => {
// Get the user id
const userId = currentUser.user.uid;
// Get a new Firestore batched write
const batch = this.db.batch();
// Create the new username document in the usernames collection with the user's id as field
const usernameRef = this.db.collection("usernames").doc(username);
batch.set(usernameRef, { userId });
// Create the new user document in the users collection with all the relevant information
const userRef = this.db.collection("users").doc(userId);
birthday = firebase.firestore.Timestamp.fromDate(new Date(birthday)); // It is neccessary to convert the birthday to a valid Firebase Timestamp
const data = {
email,
username,
name,
birthday,
};
batch.set(userRef, data);
// Commit the batch
return batch.commit();
})
.catch((err) => {
throw err;
});

我认为问题在于您在安全规则全局函数中使用了get((。将其设为本地,然后使用getAfter等待批处理写入的"终止"。

在这里,您可以看到一篇可能对您的案例有用的帖子:Firebase安全规则在get((和getAfter((之间的差异

看看Doug的回答,他解释了get和getAfer之间的区别。

最新更新