Firestore安全规则限制查询后,FirestoreRecyclerAdapter仍能获取数据问题
我设置了如下Firestore安全规则以禁止对/routes集合的查询操作:
match /routes/{routeID} { allow list, get: if false; allow delete: if false; allow update, create; }
同时使用以下Android Java代码进行查询:
Query query = mRoutesColRef .limit(50) .whereEqualTo("uid", mFirebaseUser.getUid()) .orderBy("route_end_timestamp", Query.Direction.DESCENDING); FirestoreRecyclerOptions<Route> options = new FirestoreRecyclerOptions.Builder<Route>() .setQuery(query, Route.class) .build(); mAdapter = new RidesProfileAdapter(options); mRecyclerView.setAdapter(mAdapter); mAdapter.startListening(); query.addSnapshotListener(new EventListener<QuerySnapshot>() { @Override public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) { if (value != null) { // do stuff } else { if (error != null) logEvent(mActivity, "e", "Error while addSnapshotListener in profile: " + error.getMessage()); } } });
快照监听器中如期收到权限错误:
E/Debugging: Error while addSnapshotListener in profile: PERMISSION_DENIED: Missing or insufficient permissions.
但FirestoreRecyclerAdapter和FirestoreRecyclerOptions却仍能获取到用户新增的文档。请问这是哪里出现了问题?
这是因为FirestoreRecyclerAdapter默认会读取本地缓存的数据,哪怕服务器端的查询被安全规则拦截,它依然能加载本地缓存里已有的文档——包括你新增后同步到本地的内容。
你的安全规则只限制了从服务器获取数据的list和get操作,但没禁止本地缓存的读取。当你创建新文档时,由于create权限是开放的,新文档会先写入本地缓存再同步到服务器,而FirestoreRecyclerAdapter直接从本地缓存取数据,所以能看到新增内容。
要彻底解决这个问题,核心是调整安全规则,确保只有符合条件的用户才能读取自己的文档,比如:
match /routes/{routeID} { allow list, get: if request.auth.uid == resource.data.uid; allow delete: if false; allow update, create: if request.auth.uid == request.resource.data.uid; }
这样既保证用户只能访问自己的文档,也能让本地缓存和服务器端权限保持一致,不符合权限的内容会被自动清理。
如果需要临时强制适配器只从服务器拉取数据,可以在构建FirestoreRecyclerOptions时配合服务器数据源,但这不是根本方案,正确配置安全规则才是关键。
内容的提问来源于stack exchange,提问作者nibbana

