0

我想在另一个文档的基础上验证在firestore中的读取。基本的firestore安全规则:exists()工作 - 为什么get()不是?

数据结构由2个集合组成:“执行”和“测试”。

在测试集只有1号文件,具有以下ID:SRJKCxU4HVDBdB3qyfzG和theese值:

admin true id: "SRJKCxU4HVDBdB3qyfzG" test: 1

我的安全规则是这样的:

service cloud.firestore { 
    match /databases/{database}/documents { 

    function testFunction(testId) { 
     // return exists(/databases/$(database)/documents/test/$(testId)); 
     return get(/databases/$(database)/documents/test/$(testId)).data.id == "SRJKCxU4HVDBdB3qyfzG"; 
    } 

    match /execution/{exeid} { 
     allow read, write: if testFunction("SRJKCxU4HVDBdB3qyfzG"); 
    } 

    } 
} 

如果我使用return exists(/databases/$(database)/documents/test/$(testId));一切工作如预期。但是无论如何我不能让这条线路工作return get(/databases/$(database)/documents/test/$(testId)).data.id == "SRJKCxU4HVDBdB3qyfzG"

我真的很希望我缺少简单明显的东西吗?任何帮助都很常见。如果需要,我还创建了一个演示Firebase项目和stackblitz。

感谢您的帮助。

更新 - 临时解决方案 由于存在Firestore安全规则错误,数据属性未填充。这将被修复。对于GET()工作的临时解决方案如下:

get(path).data.prop || get(path).prop

+0

我很好奇,为什么你不直接使用'exists'? –

+0

代码被简化了。真正的用例是在'get(/ databases/$(database)/ documents/test/$(testId))'上查找一个值,并将其用于验证。 – DauleDK

+0

啊,好的。使用id作为例子很可能会引起误解,因为您应该始终使用exists来检查文档是否存在。你可以同时存在并获得规则中的同一个文档,而不需要进行额外的查找(我们的系统将这些请求重复数据删除) –

回答

3

resource.id还不存在,这就是为什么你不能做到这一点。

+0

我不知道我在这里跟着你吗?这个文件:'/ databases/$(database)/documents/test/SRJKCxU4HVDBdB3qyfzG'当然存在吗? – DauleDK

+0

作为系统的一个功能。 Get()返回一个'resource',我们不支持这个id。 –

+0

好吧。但是我试图在资源上检索一个名为id的数据属性。并且此代码返回get(/ databases/$(database)/ documents/test/$(testId))。data.id ==“SRJKCxU4HVDBdB3qyfzG”'不能按预期工作。 – DauleDK

2

this Stack Overflow question,目前在火力地堡安全规则的错误:

因为错误是不填充该数据对象,你应该检查这两个属性。有没有埃塔上启动这个bug的解决方案..

临时的解决方法是更改​​代码这样:

return get(/databases/$(database)/documents/test/$(testId)).id == "SRJKCxU4HVDBdB3qyfzG" || get(/databases/$(database)/documents/test/$(testId)).data.id == "SRJKCxU4HVDBdB3qyfzG"

+0

.id和data.id是不同的字段,所以这是不正确的。 data.id是文档中名为id的用户定义字段,而不是文档的id。 –

+0

让我来检查一下。 – DauleDK

+0

您可以在控制台中测试它。创建一个新文档,然后使用不同的值添加一个名为id的字段。 –