You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:21:19