Google cloud firestore firestore安全规则是否获取动态密钥的值?

Google cloud firestore firestore安全规则是否获取动态密钥的值?,google-cloud-firestore,firebase-security,Google Cloud Firestore,Firebase Security,文件结构: { [id 1] { field1: "value", field2: "value", field3: "value" } [id 2] { field1: "value", field2: "value", field3: "value" } [id 3] { field1: "value", field2: "v

文件结构:

{
    [id 1] {
        field1: "value",
        field2: "value",
        field3: "value"
    }
    [id 2] {
        field1: "value",
        field2: "value",
        field3: "value"
    }
    [id 3] {
        field1: "value",
        field2: "value",
        field3: "value"
    }
}
地图ID参考文档,不能硬编码,但每个地图中的字段名称(字段1、字段2…)相同


有没有办法检查任何1个映射中只有1个字段发生了更改,并在满足这些条件时允许写入?

安全规则不够灵活,无法满足您的要求。这需要循环和赋值,这两种语言都不可用。我建议改为使用后端从客户端收集数据,然后检查数据是否有效。

将所有验证逻辑保留在Firestore中的一个技巧是为写入请求添加冗余。例如,您可以从客户端发送以下数据:

firestore.collection('A').doc('B').update({
“您的身份证在这里”:
字段1:‘我的新价值’,
//保留旧数据,因为我们正在更新嵌套对象
字段2:'原始值',
字段3:“原始值”
},
//这是冗余组件
meta:{id:'你的id在这里'}
});
然后,在Firestore规则中,您可以如下定义写入规则:

函数有效(){
//从请求的“冗余”部分获取ID
让metaID=request.resource.data.meta.id;
//在文档的根目录中获取已更改的键
让rootAftectedKeys=request.resource.data.diff(resource.data.affectedKeys();
//验证根键;需要包括“meta”,因为它现在也是对象的一部分
让rootChangesGood=rootAffectedKeys.hasOnly([metaID,'meta']);
//抓取有问题的嵌套对象
让nestedObjectChanges=request.resource.data[metaID].diff(resource.data[metaID]).affectedKeys();
//检查只有一个受影响的密钥
让nestedObjectChangesGood=nestedObjectChanges.size()=1;
返回rootChangesGood&&nestedObjectChangesGood;
}
允许写入:如果有效();
如您所见,我使用
metaID
变量动态访问对象的键

这种方法的优点是:(1)所有验证逻辑都在Firebase中;(2)它比执行云函数快得多(因为您只直接与Firestore通信)


然而,这种方法的缺点是,您将有这个
meta
对象浮动在周围,让每个人都能看到。除此之外,我还将添加更多验证,以确保
meta
对象本身只包含正确格式的所需数据。我强烈建议彻底测试所有可能的场景。

如果不知道字段名称,则无法从字段中获取值。你的目标是什么?为什么需要这样做?@DougStevenson相关文档包含随机ID引用的地图。我只需要允许更改其中一个贴图中的一个子值。由于只能更改1个映射,因此
changedKeys()
仅包含1项,因此获取已更改映射的id的一种方法是获取从
changedKeys()
返回的集合中的id值,但我没有找到任何关于如何执行此操作的文档。那么,有没有办法从
集合
中获取值,或者获取更改后的映射?很难想象从那块文本中你在做什么,但我认为,在这里使用随机场名对你不利。不确定你所做的是否可行。在Firestore中,这并不是一种很好的数据建模方法。@DougStevenson我稍微澄清了这个问题,你能再看一看吗?谢谢,还有,有没有办法将集合转换为列表或从集合中获取ttem,如果没有,这些功能在可预见的将来是否可以添加?如果你有新问题,请分开张贴。在堆栈Overfow上,通常会对有帮助的答案进行投票,并将其视为正确答案。