Google Firestore存储设计咨询:用户偏好、许可证及内购数据管理
嘿,很高兴你已经搭好了Google Auth和Firestore的基础框架!作为NoSQL新手,从核心需求出发设计数据结构是最稳妥的,我结合你的跨平台许可证、内购恢复场景,给你梳理一套实用的存储方案:
核心数据模型设计
1. 用户根文档(核心关联节点)
直接用Google Auth返回的用户UID作为文档ID,存在users集合下,这样能无缝关联用户身份,不用额外做用户ID映射。文档里存基础用户信息和高频访问的偏好:
// users/{uid} { "email": "user@example.com", "registerTimestamp": "2024-05-20T12:00:00Z", "lastActiveTimestamp": "2024-05-21T09:30:00Z", // 用户偏好(简单键值对直接存在这里) "preferences": { "theme": "dark", "notificationsEnabled": true, "defaultPlatform": "macOS" } }
2. 多平台许可证/应用安装集合
在用户文档下创建子集合licenses,每个文档对应一个平台的许可证记录,这样能轻松区分不同平台的授权状态,也方便后续扩展新平台:
// users/{uid}/licenses/{licenseId} (licenseId可以用Firestore自动生成,或者用平台订单ID) { "platform": "iOS", // 枚举值:iOS/macOS/Windows等 "licenseKey": "XXXX-XXXX-XXXX", "expiryDate": "2025-05-20T12:00:00Z", "status": "active", // active/inactive/expired "installTimestamp": "2024-05-20T12:30:00Z", "deviceIdentifier": "ios_123456" // 可选:绑定设备的话加这个字段 }
查询优势:用户登录后,直接拉取users/{uid}/licenses就能拿到所有平台的授权,判断当前设备是否有有效许可证。
3. 内购记录集合(支持跨平台恢复)
同样在用户文档下建子集合purchases,每个文档对应一次内购交易,保留完整交易信息,方便跨平台恢复时校验:
// users/{uid}/purchases/{purchaseId} (用苹果/谷歌的订单ID作为purchaseId更易追溯) { "productId": "premium_yearly", // 内购商品ID "platformPurchaseId": "APPLE_123456", // 平台返回的原始订单ID "platform": "iOS", "purchaseDate": "2024-05-20T12:15:00Z", "expiryDate": "2025-05-20T12:15:00Z", "isRestored": false, // 标记是否通过恢复功能获取 "status": "valid" // valid/refunded/cancelled }
跨平台恢复逻辑:用户在新平台登录后,调用平台内购恢复API拿到订单ID,然后在Firestore的purchases集合里匹配platformPurchaseId,如果存在且状态有效,就给当前平台解锁对应权限。
关键最佳实践
- 安全规则必须配置:别让用户能读写其他人的数据,最基础的规则如下,确保只有登录用户能访问自己的文档:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; // 子集合继承父文档权限 match /{subcollection}/{doc} { allow read, write: if request.auth != null && request.auth.uid == userId; } } } }
- 提前创建复合索引:如果需要按
platform和expiryDate查询有效许可证(比如where('platform', '==', 'iOS').where('status', '==', 'active')),Firestore会提示你创建复合索引,直接按提示操作就行,避免查询报错。 - 适度冗余提升性能:如果需要频繁判断用户是否有有效授权,可以在用户根文档里加一个
activeLicenses字段,存当前有效的平台列表(比如["iOS", "macOS"]),更新许可证时同步维护这个字段,减少子集合的读取次数。 - 避免嵌套过深:Firestore不建议超过2层嵌套集合,咱们现在的结构(用户文档→子集合)是最合理的,扩展性强,查询效率也高。
扩展预留
以后如果要加团队共享许可证、订阅自动续费等功能,只需要:
- 新增
teams子集合,存储团队信息和成员关联 - 在
purchases里加subscriptionRenewal字段,记录自动续费状态 - 给
licenses加teamId字段,关联团队文档
这样的结构既满足你当前的需求,也给未来的功能迭代留足了空间,要是有具体的业务细节需要调整,随时再细化!
内容的提问来源于stack exchange,提问作者mgmg
相关产品推荐
相关产品推荐

