You need to enable JavaScript to run this app. 如何在Firebase中实现支持私密账号的关注系统?
优惠活动
大模型
产品
解决方案
定价
更多

如何在Firebase中实现支持私密账号的关注系统?

数据结构调整方案

你现有users集合的基础结构可以保留,只需要新增两个根集合存储关注关系和申请即可,整体结构如下:

  • 根集合users(原有结构保留)
    • 文档ID:对应用户Firebase Auth的UID
    • 字段:
      • username: string
      • accountIsPrivate: boolean
    • 子集合userData
      • 文档userData:存储需要权限控制的隐私数据
  • 新增根集合follows:存储已生效的关注关系
    • 文档ID:用{followerUID}_{followedUID}格式拼接,避免重复写入
    • 字段:
      • followerUID: string 关注者UID
      • followedUID: string 被关注者UID
      • followTime: timestamp 关注生效时间
  • 新增根集合followRequests:存储私密账号的待处理关注申请
    • 文档ID:用{applicantUID}_{targetUID}格式拼接
    • 字段:
      • applicantUID: string 发起关注申请的用户UID
      • targetUID: string 被申请的私密账号用户UID
      • applyTime: timestamp 申请提交时间

基于这个结构可以直接实现所有需求:

  • 关注公开账号:前端直接往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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 01:27:05