给出文档类型:
import React from 'react';
import { compose, withProps } from 'recompose';
import {
withScriptjs,
withGoogleMap,
GoogleMap,
Marker,
} from 'react-google-maps';
import icon1 from '../map/icon1.svg';
import iconDead from '../map/iconDead.svg';
const API = 'YOUR_API_KEY';
const MapWithMarkers = compose(
withProps({
googleMapURL: `https://maps.googleapis.com/maps/api/js?key=${API}&callbak=initMap`,
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `800px` }} />,
mapElement: <div style={{ height: `100%` }} />,
}),
withScriptjs,
withGoogleMap,
)((props) =>
<GoogleMap
center={{ lat: 51.510228, lng: -0.132992 }}
zoom={10}
defaultOptions={{
styles: mapStyles
}}
>
{props.markers.map((place, index) => {
return (
<div>
<MarkerWithSearch
index={place.id}
position={{ lat: place.lat, lng: place.lng }}
icon={place.type}
place={place}
/>
</div>
);
})}
</GoogleMap>
);
const MarkerWithSearch = (props) => {
return (
<div>
<Marker
position={props.position}
icon={ props.icon === "alive" ?
({
url: icon1,
scaledSize: new window.google.maps.Size(45, 45)
}) :
({
url: iconDead,
scaledSize: new window.google.maps.Size(45, 45)
})}
>
</Marker>
{/* {console.log(props.position)} */}
</div>
)
要执行的约束是允许用户将其interface Post {
content: string;
sharedBy: Array<string>;
}
与uid
数组精确地连接一次。
此外,在我的单元测试中,创建了一个文档,其中sharedBy
最初是post.sharedBy
。因此,第一次更新成功,并且[]
的值变为sharedBy
,如以下查询所确认(['1']
是测试'1'
)。
此后,将执行完全相同的更新,但是它不会失败,也可以成功。
给出以下规则:
uid
为什么上面提到的第二次更新成功而不是失败?
编辑
以下是测试文件的内容:
function canShare() {
return !resource.data.sharedBy.hasAny([request.auth.uid]); // also attempted with `hasAll`
}
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /posts/{postId} {
allow read: if true;
allow write: if request.auth != null && canShare();
}
}
}
答案 0 :(得分:1)
我认为安全规则中目前没有任何方法可以强制数组仅包含唯一值。尽管客户端可以使用array-union
运算符来确保确实如此,但恶意客户端可以添加重复条目。
确保Firestore中唯一性的唯一方法是确保值是键。因此,您可以将sharedBy
制成一个地图,其中的密钥是用户的UID。这样,您可以确保每个UID仅出现一次,因为映射中的键在定义上是唯一的。
另一个选择是将sharedBy
元素存储在子集合中,并且在那里也将UID用作文档ID。这样,系统就可以再次确保ID是唯一的。
最后一个选择是仅允许通过Cloud Function或某些其他受信任的过程更新sharedBy
数组,您的代码可以在其中强制执行此业务规则。