Javascript 为什么我的Firebase Firestore安全规则允许对现有文档执行.set()操作,但.set()缺少字段

Javascript 为什么我的Firebase Firestore安全规则允许对现有文档执行.set()操作,但.set()缺少字段,javascript,firebase,google-cloud-firestore,mocha.js,firebase-security,Javascript,Firebase,Google Cloud Firestore,Mocha.js,Firebase Security,这是我在stackoverflow上提出的第一个问题,所以如果我遗漏了问题的某些方面,请告诉我 我的目标是理解为什么当创建的文档缺少下面列出的firestore规则所需的字段时,下面显示的mocha测试会通过 摩卡测试代码(请注意,项目ID已检查并正常工作,但此处省略) 消防队规则 rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { function docum

这是我在stackoverflow上提出的第一个问题,所以如果我遗漏了问题的某些方面,请告诉我

我的目标是理解为什么当创建的文档缺少下面列出的firestore规则所需的字段时,下面显示的mocha测试会通过

摩卡测试代码(请注意,项目ID已检查并正常工作,但此处省略)

消防队规则

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    function documentFieldsCheckOut(requiredFields, allowedFields){
      let requiredAndAllowed = requiredFields.concat(allowedFields);
      return request.resource.data.keys().hasAll(requiredFields) &&
             request.resource.data.keys().hasOnly(requiredAndAllowed);
    }

    function updateHasOnlyAllowedFields(allowedFields){
      return debug(request.resource.data.keys()).hasOnly(allowedFields);
    }

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

    match /posts/{postID} {
   
      allow update: if ((resource.data.authorID == request.auth.uid) || userIsModerator()) 
                        && updateHasOnlyAllowedFields(["visibility", "content"]);
      
      allow create: if (request.resource.data.authorID == request.auth.uid) &&
                        documentFieldsCheckOut(["authorID", "content", "visibility", "headline"], 
                                                ["photo", "location", "tags"]);
    }

 }
}
注意:注释掉
wait admin.doc(postPath).set({authord:myID,content:“content”,visibility:“private”,headline:“headline”})导致测试按预期失败。

此外,将
中的.set更改为.update将等待firebase.assertsuccessed(docRef.set({}))还会导致测试按预期失败。

如果我理解正确,您会问为什么此调用成功:

const admin = getAdminFirestore();
admin.doc(postPath).set({authorID:myID, content:"content", 
                                   visibility:"private",
                                   headline:"headline"});
使用管理权限的调用绕过数据库的安全规则。因此,无论您的安全规则如何,此调用都不会被它们拒绝


第二次写入操作不同:

const db = getFirestore(myAuth);
const docRef = db.doc(postPath);
docRef.set({})

这一次,据我所知,您将通过一个非管理员参考,这意味着写入必须遵守安全规则才能被接受。

非常感谢您的快速回复!问题是为什么写操作
docRef.set({})
成功,而下面的安全规则应该拒绝写操作允许创建:如果documentFieldsCheckOut([“作者”、“内容”、“可见性”、“标题”]、“照片”、“位置”、“标记”]);`执行相同的.docRef.set({})操作而不首先创建具有管理权限的文档失败。换句话说,规则似乎允许使用绕过创建规则的.set()来“覆盖”现有数据,但我敢打赌我遗漏了什么!你可能想澄清你的问题,因为我仍然很难理解为什么你认为在这种情况下应该拒绝第二封信。谢谢你让我回顾我的问题!在进一步减少代码并运行更多测试之后,我发现我错误地认为.set()方法总是算作Firestore规则中的create。但是,当文档位于.set()之前时,它似乎被算作“更新”方法。由于我在规则中授予了允许不包含必填字段的更新的权限,用户可能会将其文档“更新”为空白文档:D请让我知道这是否是错误的结论,并再次感谢您的帮助!!!
const db = getFirestore(myAuth);
const docRef = db.doc(postPath);
docRef.set({})