【发布时间】:2019-05-25 21:45:58
【问题描述】:
我正在尝试将 Cloud Firestore 与我的 android 应用程序一起使用。 所以我要存储 3-4 个字段。所以我将举一个汽车收藏的例子。 有一个“汽车”集合。汽车集合的文档具有以下字段: 制造商、型号、最高速度。
我正在使用 android 添加数据,代码如下:
dManufacturer = "Hyundai"
dModel = "Kona"
dTopSpeed ="150"
Map<String, Object> car = new HashMap<>();
car.put("manufacturer", dManufacturer);
car.put("model", dModel);
car.put("top_speed",dTopSpeed);
db.collection(cars")
.add(car)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
@Override
public void onSuccess(DocumentReference documentReference) {
Log.d("firebaseab", "DocumentSnapshot added with ID: " + documentReference.getId());
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w("firebaseab", "Error adding document", e);
}
});
因此,使用我的应用程序的任何用户都应该只能添加 1 个汽车文档,如果该文档的所有字段值都与集合中的文档相似,则不应添加数据。
我会告诉我已经尝试过和正在考虑的选项,但请帮助告诉我实现这一目标的最佳方法以及如何实现这一目标。
所以我想通过创建验证安全规则来节省查询配额以尽可能地保持在免费计划内,但我不明白它是如何工作的,所以我不断收到错误或权限被拒绝。
我尝试过的方法:
1) 我尝试为“!=”与集合中的文档匹配到我在上面从 android 执行的创建请求中的一个规则,但它给了我错误。我还没有完全理解发生了什么。规则是这样的:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read;
}
// match /{document=**} {
// //allow create: if document != request.resource.data;
// allow create: if document.manufacturer == "Google";
// }
match /cars/{car} {
allow create : if request.resource.data.manufacturer != resource.data.manufacturer
&& request.resource.data.model != resource.data.model
&& request.resource.data.topSpeed != resource.data.topSpeed;
}
}
}
但是上面给出了错误并且没有工作。
不知道如何使用 !exists 来比较具有相同字段值的文档是否存在。它们可以有不同的文档 ID,但如果字段的值相同,那么我不想添加另一个具有相同字段值的文档。
我正在思考但不知道哪个是正确的或如何实现的方式:
1) 会创建一个包含我需要匹配的所有值的复合索引吗?但是我如何编写安全规则,这样我就不必从我的代码中检查或执行获取查询。
2) 我是否应该创建文档 ID 作为复合索引(但我应该如何做以及如何编写安全验证规则)
3) 我应该从客户端以 "manufacturer_model_topspeed" 格式创建文档 ID。所以这将是根据我的例子 - “现代_科纳_150”。这是否有助于保持独特性。如果这样的话,当输入具有相同文档 ID 的文档时,权限将被拒绝。那我应该如何在客户端处理它。我可以从 Cloud Firestore 发送描述此特定创建被拒绝事件的特定消息或值吗?
4) 我是否应该在 android 中使用 Device.Id 作为文档 ID 以匹配特定设备,所以如果用户添加了文档,那么他不能添加更多。但这可能会造成文档字段数据的重复。我在问这个关于如何写安全规则,让已经写过文档的人不能再写了。
5)我还想知道是否找到了拒绝重复数据的方法,然后如何在 android 中接收该拒绝,让我知道拒绝不是未处理的错误,因此我可以保存在设备上以不联系 firestore未来。
有没有其他更好的方法来解决这个问题...请告诉我。我什至可以使用一些客户端代码来使用 where 子句等,但我想最小化读取配额。如何在使用最小读/写配额的情况下做到这一点。我是 Cloud Firestore 的初学者。
【问题讨论】:
标签: android firebase google-cloud-firestore firebase-security