如何在Firebase中实现支持私密账号的关注系统?
数据结构调整方案
你现有users集合的基础结构可以保留,只需要新增两个根集合存储关注关系和申请即可,整体结构如下:
- 根集合
users(原有结构保留)- 文档ID:对应用户Firebase Auth的UID
- 字段:
username: stringaccountIsPrivate: boolean
- 子集合
userData- 文档
userData:存储需要权限控制的隐私数据
- 文档
- 新增根集合
follows:存储已生效的关注关系- 文档ID:用
{followerUID}_{followedUID}格式拼接,避免重复写入 - 字段:
followerUID: string 关注者UIDfollowedUID: string 被关注者UIDfollowTime: timestamp 关注生效时间
- 文档ID:用
- 新增根集合
followRequests:存储私密账号的待处理关注申请- 文档ID:用
{applicantUID}_{targetUID}格式拼接 - 字段:
applicantUID: string 发起关注申请的用户UIDtargetUID: string 被申请的私密账号用户UIDapplyTime: timestamp 申请提交时间
- 文档ID:用
基于这个结构可以直接实现所有需求:
- 关注公开账号:前端直接往
follows集合写入对应关系即可 - 关注私密账号:前端先往
followRequests集合写入申请,等待对方处理 - 查看自己的关注列表:查询
follows集合中followerUID == 自身UID的所有文档,再关联查询对应用户的公开信息即可 - 私密账号处理申请:查询
followRequests集合中targetUID == 自身UID的所有文档,同意则在follows集合新增对应关系后删除申请,拒绝则直接删除申请即可
Firestore规则编写思路
所有规则的前提是用户已登录,即request.auth != null,各场景的规则示例如下:
1. users集合公开信息权限
用户文档的公开字段(用户名、是否私密等)所有登录用户都可查看,只有用户本人可以修改自己的资料:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{uid} { allow read: if request.auth != null; allow write: if request.auth != null && request.auth.uid == uid; } } }
2. userData隐私数据权限
这部分是核心控制逻辑,满足三个条件任意一个即可读取:是用户本人、账号公开、账号私密但访问者是已关注用户:
match /users/{followedUID}/userData/userData { allow read: if request.auth != null && ( request.auth.uid == followedUID || !get(/databases/$(database)/documents/users/$(followedUID)).data.accountIsPrivate || exists(/databases/$(database)/documents/follows/$(request.auth.uid)_$(followedUID)) ); allow write: if request.auth != null && request.auth.uid == followedUID; }
3. follows集合权限
仅允许用户查询自己的关注/被关注列表,仅允许用户自己取消关注,仅允许对公开账号直接发起关注:
match /follows/{followDocId} { allow read: if request.auth != null && ( resource.data.followerUID == request.auth.uid || resource.data.followedUID == request.auth.uid ); allow create: if request.auth != null && request.resource.data.followerUID == request.auth.uid && ( !get(/databases/$(database)/documents/users/$(request.resource.data.followedUID)).data.accountIsPrivate ); allow delete: if request.auth != null && resource.data.followerUID == request.auth.uid; }
4. followRequests集合权限
仅允许申请人和被申请人查看申请,仅允许用户对私密账号发起未重复的申请,仅允许双方删除申请:
match /followRequests/{requestDocId} { allow read: if request.auth != null && ( resource.data.applicantUID == request.auth.uid || resource.data.targetUID == request.auth.uid ); allow create: if request.auth != null && request.resource.data.applicantUID == request.auth.uid && ( get(/databases/$(database)/documents/users/$(request.resource.data.targetUID)).data.accountIsPrivate && !exists(/databases/$(database)/documents/follows/$(request.auth.uid)_$(request.resource.data.targetUID)) && !exists(/databases/$(database)/documents/followRequests/$(request.auth.uid)_$(request.resource.data.targetUID)) ); allow delete: if request.auth != null && ( resource.data.applicantUID == request.auth.uid || resource.data.targetUID == request.auth.uid ); }
如果需要更高的安全性,可以将follows集合的创建权限仅开放给Firebase云函数的服务账号,私密账号的关注关系统一由处理申请的云函数写入,避免前端绕过规则。
内容的提问来源于stack exchange,提问作者Alexanderbira
相关产品推荐
相关产品推荐

