我的应用程序中有一个recyclerview,它带有一个get,它检索集合中的所有文档。每个文档都包含创建它的人的uid。我想实现一个安全规则,在该规则中,您仅检索与所有者的uid相匹配的文档。看起来很琐碎,但我无法使其正常工作。
数据库具有这样的结构
cars
|
|-documentA
|-documentB
|-documentC
每个文档
documentA
|
|
|-fieldA: aaa
|-fieldB: bbb
|-userId: aklsjdaosjfpasf
firestore的安全规则
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{cars=**}/{carId} {
allow read: if request.auth.uid == resource.data.userId;
allow write: if request.auth.uid != null;
}
}
}
编辑 查询:
query = firestore.collection("cars").limit(10L)
用于对recyclerview进行查询的Firestore适配器
public abstract class FirestoreAdapter<VH extends RecyclerView.ViewHolder>
extends RecyclerView.Adapter<VH> {
private static final String TAG = "Firestore Adapter";
private Query mQuery;
private ListenerRegistration mRegistration;
private ArrayList<DocumentSnapshot> mSnapshots = new ArrayList<>();
public FirestoreAdapter(Query query) {
mQuery = query;
}
public void startListening() {
// TODO(developer): Implement
}
public void stopListening() {
if (mRegistration != null) {
mRegistration.remove();
mRegistration = null;
}
mSnapshots.clear();
notifyDataSetChanged();
}
public void setQuery(Query query) {
// Stop listening
stopListening();
// Clear existing data
mSnapshots.clear();
notifyDataSetChanged();
// Listen to new query
mQuery = query;
startListening();
}
@Override
public int getItemCount() {
return mSnapshots.size();
}
protected DocumentSnapshot getSnapshot(int index) {
return mSnapshots.get(index);
}
protected void onError(FirebaseFirestoreException e) {};
protected void onDataChanged() {}
}
答案 0 :(得分:2)
您必须注意,安全规则不是过滤器,如documentation所述:
一旦保护好数据并开始编写查询,请记住 安全规则不是过滤器。 您无法为以下内容编写查询 集合中的所有文档,并期望Cloud Firestore能够 仅返回当前客户有权访问的文档 访问。
使用
query = firestore.collection("cars").limit(10L)
您要独立于userId
查询,因此出现了问题。
您需要使用whereEqualTo()
修改查询,如下所示:
//get the value of uid
query = firestore.collection("cars").whereEqualTo("userId", uid).limit(10L)
答案 1 :(得分:1)
根据评论,我认为这可能是解决方案。根据OP,所有用户都应该能够注册汽车,但是只有创建汽车的用户才能看到汽车。
在这种情况下,正确的权限应如下所示:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /cars/{carId} {
allow read, write: if request.auth.uid == resource.data.userId;
allow create: if request.auth.uid != null;
}
}
}
对于2版之前的规则,
许可URL也存在问题,您可以使用以下语法来匹配集合中的所有文档:/cars/{documemts=**}/
,但是您的路径/{cars=**}/{carId}
无效,因此该规则永远不会为您的查询强制执行。
路径/cars/{carId}
将引用集合'cars'中的任何文档,并将该文档的名称存储为'carId'。