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

How to check if Google Play Subscription is active on client-side or server-side

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

更多信息

我使用 Pub/Sub 使用云函数在用户帐户 (Firebase 身份验证) 中保存用户订阅到 firestore,我在本地数据库中保存相同的订阅数据。

我试过的

要检查用户帐户中的链接订阅是否有效,我正在检查 expiryTimeMillis is after the current date or 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`);

您的方向非常正确,但您偏离了一个微妙的点:

I thought about using the server timestamp but that would be hard since user subscription is subjected to timezone (as far as I know).

这不太正确。 expiryTimeMillis 定义自纪元以来的毫秒数(也称为 Unix timestamps), which is independent of time zones. As the linked article notes, the Unix epoch is 00:00:00 UTC on 1 January 1970. That same time is 4:00:00 PM December 31, 1960 Pacific Standard Time, but both of those times in their respective time zones have the same timestamp0.

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

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