Firestore自动生成ID的文档添加子集合及关注功能实现咨询
问题1解答
- 不需要必须实现方案(c),选择完全取决于你需要展示的页面内容:
- 如果仅需要展示「当前登录用户的关注列表」,仅实现方案(a)即可
- 如果仅需要展示「任意用户的粉丝列表」,仅实现方案(b)即可
- 如果两类列表都需要展示,优先选方案(c),不要尝试用单集合反向查询,反而会大幅提升成本
- 三种方案的成本差异和你的查询场景强相关:仅写操作层面,c比a/b多1次写,成本差一倍;但如果用a/b单方案支撑双向查询,需要遍历全量用户的子集合,产生的读费用会是方案(c)的几十到上百倍,反而更贵。绝大多数社交类产品两类列表都需要展示,方案(c)是长期来看成本最低的选择。
问题2解答
你遇到的问题很好解决,QueryDocumentSnapshot自带reference属性,直接取即可获得对应文档的DocumentReference,不需要提前知道自动生成的文档ID,参考代码如下:
// 查询当前登录用户对应的users文档 var userQuery = await instance.collection('users').where( 'userId', isEqualTo: _auth.currentUser.uid, ).get(); // 直接从快照获取DocumentReference var currentUserDoc = userQuery.docs[0].reference; // 基于该引用创建子集合文档 await currentUserDoc.collection('followees').doc('被关注用户的uid').set({ // 自定义存储字段 });
不存在「自动生成ID的文档不能加子集合」的说法,另外更推荐你后续调整结构,直接把FirebaseAuth的uid作为users集合的文档ID,这样不需要额外查询就能直接拿到用户文档引用,省掉一次查询费用,逻辑也更简洁。
问题3解答
数组存储方案仅适合关注上限极低的场景(比如单用户关注数不超过1000),绝大多数社交场景下不可取,核心弊端有两个:
- Firestore单文档最大容量为1MB,按单个uid占30字符计算,单个文档最多只能存储3万左右的uid,很容易触达存储上限
- 分页拉取关注列表、查询两个用户是否互关、统计关注总数这类常见需求,用数组实现的复杂度和成本远高于子集合方案,后续功能迭代会非常受限
内容的提问来源于stack exchange,提问作者森口万太郎
相关产品推荐
相关产品推荐

