Firebase Firestore规则:只有在auth.id == request.data.id时才允许读写。

huangapple go评论127阅读模式
英文:

Firebase Firestore Rules: Allow read/write only if auth.id == request.data.id

问题

这是您提供的一段代码和问题描述。以下是翻译的部分:

我正在使用以下规则:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    
    // Documents can only be read or written by authenticated users
    match /{document=**} {
      allow read, write: if request.auth != null && request.auth.uid == resource.data.uid;
    }
  }
}

根据我的理解,这应该意味着:“只有在用户经过身份验证且其 uid 与他们正在读取或写入的文档的 uid 匹配时,才允许读取或写入操作”。

然而,我不断收到“permission-denied”错误。

这是我正在使用的代码(Dart/Flutter):

static FirebaseFirestore instance = FirebaseFirestore.instance;
static CollectionReference colRef = instance.collection('someCollection');

使用此包装方法(已更新):

Future<void> updateData() async {
    final uid_ = FirebaseAuth.instance.currentUser!.uid;
    final data = {'uid': uid_};
    await colRef.doc(uid_).set(data);
}

基本上,我将用户的 uid 传递给 updateData 函数,并确保文档具有相同的 uid,以符合规则。

我做错了什么?

编辑:

我尝试过的事情:

  1. 确保用户已经通过身份验证,以及将正确的 uid 传递给包装函数。

  2. 使用 set 方法而不是 update 方法,以避免如果文档尚不存在会出现任何问题。

  3. 在了解有关 resource 对象的更多信息后,将 uid 附加到 data 映射中。

  4. rules 之间切换,从 request.auth.uid == resource.data.uidrequest.auth.uid == resource.id

  5. 将规则更改为仅为 request.auth != null,这最终按预期工作,但对于我的舒适区来说有点太宽泛。然而,这证明了用户已通过身份验证。我只需要一种方法来将 auth.uid 与数据映射对象内的 document.iduid 进行比较。

  6. 更改包装方法以明确使用 FirebaseAuth.instance

具体错误:

flutter: [cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.

英文:

I am using these rules:

rules_version = &#39;2&#39;;
service cloud.firestore {
  match /databases/{database}/documents {
    
    // Documents can only be read or written by authenticated users
    match /{document=**} {
      allow read, write: if request.auth != null &amp;&amp; request.auth.uid == resource.data.uid;
    }
  }
}

From my understanding, this should mean: "Allow read or write operations ONLY IF the user is authenticated and their uid matches the uid of the document they are reading or writing".

Yet, I continually get permission-denied errors.

This is the code I am using (Dart/Flutter):

  static FirebaseFirestore instance = FirebaseFirestore.instance;
  static CollectionReference colRef = instance.collection(&#39;someCollection&#39;);

With this wrapper method (updated):

Future&lt;void&gt; updateData() async {
    final uid_ = FirebaseAuth.instance.currentUser!.uid;
    final data = {&#39;uid&#39;: uid_};
    await colRef.doc(uid_).set(data);
}

Basically, I am passing the user uid to the updateData function, and ensuring the document has the same uid so it conforms with the rules.

What am I doing wrong?

EDIT:

Things that I have tried:

  1. Ensured that the user was authenticated and that the correct uid was being passed to the wrapper function.

  2. Used the set method instead of the update method to avoid any issues if the document does not yet exist.

  3. Appended the uid to the data map after learning more about the resource object.

  4. Toggled the rules between request.auth.uid == resource.data.uid and request.auth.uid == resource.id.

  5. Changed the rule to only be request.auth != null, which ended up working as expected, but is a bit too broad for my comfort zone. Yet, this is proof that the user is authenticated. I just need a way to compare the auth.uid with either the document.id or uid within the data map object.

  6. Changed the wrapper method to explicitly use FirebaseAuth.instance.

The specific error:

flutter: [cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.

答案1

得分: 1

The key was that you're trying to write the uid field for the first time.

Your rules now do this:

resource.data.uid

The resource here refers to the document as it exists before the current operation, which doesn't seem to have the uid value yet.

If you want to refer to the document as it'll exist after the write operation (if that write operation is allowed), use:

request.resource.data.uid

Also see the documentation on the resource and request.resource variables.

英文:

The key was that you're trying to write the uid field for the first time.

Your rules now do this:

resource.data.uid

The resource here refers to the document as it exists before the current operation, which doesn't seem to have the uid value yet.

If you want to refer to the document as it'll exist after the write operation (if that write operation is allowed), use:

request.resource.data.uid

Also see the documentation on the resource and request.resource variables.

huangapple
  • 本文由 发表于 2023年4月11日 04:17:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75980405.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定