如何检查 Google Play 订阅是不是在客户端或服务器端处于活动状态

Posted

技术标签:

【中文标题】如何检查 Google Play 订阅是不是在客户端或服务器端处于活动状态【英文标题】:How to check if Google Play Subscription is active on client-side or server-side如何检查 Google Play 订阅是否在客户端或服务器端处于活动状态 【发布时间】:2020-09-29 12:58:04 【问题描述】:

基本上,我想要的是能够检查用户帐户中的链接订阅(firebase auth with firestore)是否处于活动状态,即使用户使用 iPhone 或使用具有 firebase 功能的 play 开发人员 API 的 Web 应用程序登录(服务器-side) 或特定平台代码(客户端),例如 android kotlin。

更多信息

我正在使用 Pub/Sub 使用云功能将用户订阅保存在用户帐户 (Firebase auth) 中的 firestore 上,并且我正在将相同的订阅数据保存在本地数据库中。

我尝试了什么

要检查用户帐户中的链接订阅是否处于活动状态,我正在检查expiryTimeMillis 是否在当前日期之后或autoRenewing 已启用:

suspend fun isPremiumActive(userId: String): Boolean 
  val userSubscriptionData = localDB.getUserSubscription(userId)
        if (userSubscriptionData == null)
            return false
        else
            return Date(userSubscriptionData.expiryTimeMillis).after(Date()) ||
                    userSubscriptionData.autoRenewing
    

但是使用 java Date 有很多缺点,因为它受设备日期的影响

我考虑过使用服务器时间戳,但这会很困难,因为用户订阅受时区限制(据我所知)。

那么有没有其他方法可以检查订阅当前是否处于活动状态?我错过了什么吗?

一些用例

用户可以登录(在应用程序中使用 firebase 身份验证)并且该帐户具有关联的订阅,因此如果关联的订阅有效,即使设备没有相同的帐户要支付,我也应该提供高级功能订阅,甚至用户正在使用 iPhone,所以这就是我不能打电话的原因:

billingClient.queryPurchases()

更新

此打字稿代码是否被认为可以安全检查订阅是否处于活动状态?

const serverTime = admin.firestore.Timestamp.now().toDate()
const subscriptionTime = new Date(subscripton.exipryTimeInMilis)
if (subscripton.autoRenewing || subscriptionTime > serverTime)
    console.log(`subscription is active`);

【问题讨论】:

【参考方案1】:

你在正确的轨道上,但你在一个微妙的点上偏离了:

我考虑过使用服务器时间戳,但这会很困难,因为用户订阅受时区限制(据我所知)。

这不太正确。 expiryTimeMillis 定义为自 Epoch(也称为 Unix timestamps)以来的毫秒数,它与时区无关。正如链接文章指出的那样,Unix 纪元是 1970 年 1 月 1 日的 00:00:00 UTC。同一时间是太平洋标准时间 1960 年 12 月 31 日下午 4:00:00,但这两个时间都在各自的时区 @ 987654322@:0.

因此,您的直觉是正确的:您应该使用服务器的时间戳在服务器端检查这一点。由于您描述的原因,任何检查设备的尝试都是不可靠的:它取决于设备的时间以及用户可能使用设备时间进行的任何恶作剧,是否及时向前移动以在他们最喜欢的游戏中获得更多宝石,或向后旅行以尝试延长过期的订阅(也许是您的!)。

这也将解决检查设备是否未使用订阅登录到 Google 帐户或使用 iPhone 的问题,因为您可以将系统中的帐户与后端中的订阅相关联。

【讨论】:

正是我想要的,就我而言,我将订阅时间与服务器时间戳进行比较:***.com/a/59676510/6470661 我已经根据你的回答更新了问题,你认为这种检查订阅的方式安全吗? 我对@9​​87654324@ 文档的阅读表明autoRenewing 检查是多余的,因为在这种情况下expiryDate应该总是在未来,但我认为像你一样检查它不会引起任何问题。否则,您问题末尾的逻辑对我来说是正确的。

以上是关于如何检查 Google Play 订阅是不是在客户端或服务器端处于活动状态的主要内容,如果未能解决你的问题,请参考以下文章

Google play billing API:如何了解用户是不是订阅?

Google Play 仅在订阅列表中显示应用名称

通过 Google Play 支付的应用内订阅和订阅自动续订,是不是需要通过 Google Play 安装应用?

检测当前订阅是否在Google Play商店试用版中?

如何检查 Android 设备上是不是有可用的 Google Play 游戏帐户?

检测当前订阅是不是为 Google Play 商店的试用版?