React-native-iap: 每次getAvailablePurchases返回不同的数组

创建于 2019-08-09  ·  13评论  ·  资料来源: dooboolab/react-native-iap

版本的react-native-iap

3.3.9(但在3.0.0及更高版本中也经历过)

本机版本

0.59.9

您遇到错误的平台(IOS或Android还是两者兼有?)

iOS(未在Android上测试)

预期行为

每次我调用getAvailablePurchases都使用相同的数组
每次相同的数组长度

实际行为

每次我调用getAvailablePurchases都使用不同的数组
每次我调用getAvailablePurchases时数组长度不同

经过测试的环境(仿真器?真实设备?)

真实设备

重现行为的步骤

我认为这仅在很多交易中可见,但无法确认。 我的沙盒帐户有50笔以上的交易。

handleOnPressRestore = async () => {
  return this.setState({ isLoadingRestorePurchases: true }, async () => {
    try {

      // Get the previous purchases of the current user
      const purchases = await RNIap.getAvailablePurchases();

      // Get the latest receipt from the purchases to validate
      const { transactionReceipt, productId, transactionDate } = this.getLatestPurchase(purchases);

      console.log(purchases.length, productId, transactionDate);

      // Validate the receipt on our server
      await this.props.validateSubscriptionReceipt(productId, transactionReceipt);

      // The validation result is handled in componentDidUpdate
    } catch (err) {
      throw err;
    } finally {
      this.setState({ isLoadingRestorePurchases: false });
    }
  });
}

getLatestPurchase = (purchases: RNIap.ProductPurchase[]): RNIap.ProductPurchase => {
  // First, sort the array, so the latest purchase is on top
  // https://github.com/dooboolab/react-native-iap/issues/532#issuecomment-503174711
  const sortedPurchases = purchases.sort((a, b) => b.transactionDate - a.transactionDate);

  const purchase = sortedPurchases[0];

  return purchase;
}

使用上面的代码,当我按“恢复购买”时,每次都会得到不同的日志:

按“恢复购买”六次,然后等待一段时间,以使结果进入:

// purchases.length, productId, transactionDate
9 "com.app.sub" 1565182529000
21 "com.app.sub" 1565181329000
22 "com.app.sub" 1565183001000
42 "com.app.sub" 1565183001000
53 "com.app.sub" 1565182529000
55 "com.app.sub" 1565183001000
15 "com.app.sub" 1565182529000

我希望数组总是一样,对不对? 这里发生了什么事?

每次我运行getAvailablePurchases()都是不同的

📱 iOS 🙏 help wanted 🚶🏻 stale

最有用的评论

我还在所有事务上运行了一个循环,但无法使用finishTransactionIOS删除它们。 我的交易是自动续订。

所有13条评论

我也看到了。 真正危险的是,结果中可能没有最新的有效收据。

从看这个模块的代码来看,老实说这看起来像是苹果公司的问题,因为这个模块实际上只是传递了restoreCompletedTransactions()

我想知道getPurchaseHistory()是否是用于订阅的好选择。 我目前正在使用它作为替代方法,因为这给了我可靠的结果。 我的应用程序中没有其他任何购买,只有订阅。

如该包装的iap文档中所述, getAvailablePurchases()在谈论耗材。 订阅不是“可消耗”或“非消耗”产品。 这是“自动续订的订阅”,那么getPurchaseHistory()应该怎么做?

Screenshot 2019-08-16 at 18 11 13

我发现getPurchaseHistory()也给出了不同的数组长度。 好像请求的频率影响了它。 最终,事实证明这对我们而言并不重要,一旦发送了任何交易收据进行验证,所有收据都由Apple返回到latest_receipt_info数组中,这对我们来说至关重要。

我遇到了同样的问题(不知道这是否是沙箱模式错误)。 另外,当我在真实设备中切换Apple ID时,将退回使用另一个帐户进行的购买。

例如:
1-我通过[email protected]帐户
2-将Apple ID切换到[email protected]
3-getAvailablePurchases返回使用[email protected]帐户进行的购买的

我发现的另一个问题是,如果我还原设备(恢复出厂设置),两种方法getPurchaseHistory()getAvailablePurchases都会得出随机结果

苹果对恢复购买的回应是:

"Users restore transactions to maintain access to content they've already purchased. For example, when they upgrade to a new phone, they don't lose all of the items they purchased on the old phone. Include some mechanism in your app to let the user restore their purchases, such as a Restore Purchases button."

如@ ssg-luke所述,找到了一个有关restoreCompletedTransactions的不同结果的Apple开发者论坛主题。

https://forums.developer.apple.com/thread/115242

也许这是有关的:

似乎您是指一个用户有很多交易,而该应用尚未为其调用finishTransaction。
https://forums.developer.apple.com/thread/115242#thread -post-355444

我在同一设备上有其他沙箱帐户。 那么,难道是同一设备上不同帐户的交易被搞砸了,根本没有“完成”吗?

但是,我确实在所有事务上运行了一个循环,并在所有事务上调用了finishTransactionIOS 。 但这并没有使它们消失或导致getAvailablePurchases()的可靠输出...也许是因为我已经在使用较新的沙箱帐户并且交易是从较旧的沙箱帐户进行的?

也可以解释@fcandiani的经历。

我发现getPurchaseHistory()也给出了不同的数组长度。 好像请求的频率影响了它。 最终,事实证明这对我们来说并不重要,一旦发送了任何交易收据以进行验证,所有收据都由Apple以last_receipt_info数组的形式返回,这对我们来说至关重要。

感谢您提供@ ssg-luke的信息,我将做同样的事情。

我还在所有事务上运行了一个循环,但无法使用finishTransactionIOS删除它们。 我的交易是自动续订。

面对几乎一样。 我当时正在创建一个问题,但是决定将所有信息放在这里,以帮助其他人找到问题和解决方案。

版本的react-native-iap

3.5.9

本机版本

0.60.5

您遇到错误的平台(IOS或Android还是两者兼有?)

的iOS

  • 相同的代码已在生产中的Android上完美运行

预期行为

用户订阅一次getAvailablePurchases应该只返回一次购买

实际行为

getAvailablePurchases返回多个购买,

经过测试的环境(仿真器?真实设备?)

具有新沙箱帐户的真实设备。

重现行为的步骤

  • https://appstoreconnect.apple.com/access/testers上创建沙盒测试用户
  • 在xcode上构建并运行项目
  • 调用getAvailablePurchases ,不返回任何购买信息(如预期的那样)
  • 订阅一些产品
  • 我的purchaseUpdatedListener被调用,而我调用的RNIap.finishTransactionIOS(subscription.transactionId);只返回undefined (就像我想的那样)
  • 调用getAvailablePurchases ,返回一次购买(如预期的那样)
  • 重新加载应用程序
  • 调用getAvailablePurchases ,返回两次购买,每个transactionId
{
   originalTransactionDateIOS: 1571144840000
   originalTransactionIdentifierIOS: "1000000579413333"
   productId: "io.appmasters.lowcarb.development"
   transactionDate: 1571145019000
   transactionId: "1000000579415509"
   transactionReceipt: "MIIVnQYJKoZIhvcN..."
},
{
   originalTransactionDateIOS: 1571144840000
   originalTransactionIdentifierIOS: "1000000579413333"
   productId: "io.appmasters.lowcarb.development"
   transactionDate: 1571144839000
   transactionId: "1000000579416705"
   transactionReceipt: "MIIVnQYJKoZIhvcN...."
}
  • 再次重新加载应用程序
  • 调用getAvailablePurchases ,返回三个购买,每个transactionId (与上一个结果不同):
{
   originalTransactionDateIOS: 1571144840000
   originalTransactionIdentifierIOS: "1000000579413333"
   productId: "io.appmasters.lowcarb.development"
   transactionDate: 1571145739000
   transactionId: "1000000579423546"
   transactionReceipt: "MIIb1AYJKoZIhvcN..."
},{
   originalTransactionDateIOS: 1571144840000
   originalTransactionIdentifierIOS: "1000000579413333"
   productId: "io.appmasters.lowcarb.development"
   transactionDate: 1571145019000
   transactionId: "1000000579426352"
   transactionReceipt: "MIIb1AYJKoZI..."
},{
   originalTransactionDateIOS: 1571144840000
   originalTransactionIdentifierIOS: "1000000579413333"
   productId: "io.appmasters.lowcarb.development"
   transactionDate: 1571144839000
   transactionId: "1000000579426353"
   transactionReceipt: "MIIb1AYJKoZIhvcN..."
}
  • 再次重新加载应用程序
  • 调用getAvailablePurchases ,返回四次购买,每个transactionId (与上一个结果不同)...

从我在文档上阅读的内容以及在Android上发生的事情来看,这似乎都不是正确的行为。

感谢您的帮助。

getAvaialblePurchases()在我的沙箱测试帐户中返回了150多个结果。 我决定根本不使用getAvailablePurchases(),而将最后一次购买存储在设备和服务器上。 如果应用程序被删除或用户移动到新手机,我们在服务器上的最后一次购买仍将与公司用户ID和平台(iOS或Android)相关联。 调用getAvailablePurchases()大约需要一分钟,有时会调用此触发器来触发购买更新的侦听器,以尝试恢复多个购买。 我们修改了这样的流程:
1)用户登录设备时:
a)查看我们的服务器上是否有针对该用户和平台的有效最后一次购买。
b)如果服务器上没有记录,请查看数据库中是否有本地保存的购买
c)如果没有或已过期,请显示订阅视图。
最初,我们调用getAvailablePurchases()并尝试查看上一次购买是否仍然有效。 不知道这是否对其他人有帮助,但是我们不再遇到与此有关的问题。 我们正在作出反应59,这是我们必须应对的另一种痛苦。

@ramakula ,如果用户取消订阅,该怎么办?

按照您所说的方式,您会将订阅保留在数据库上,直到结束日期为止,然后“看到”不再可用的购买。

嘿,看来这个问题最近没有任何活动。 问题是否已解决,还是仍然需要社区的关注? 如果没有其他活动,则可能已关闭此问题。 您也可以将此问题标记为“供讨论”或“良好的第一期”,我将其保留为开放状态。 感谢你的贡献。

长时间不活动后结束此问题。 如果此问题在最新版本中仍然存在,请随时创建具有最新信息的新问题。

getAvaialblePurchases()在我的沙箱测试帐户中返回了150多个结果。 我决定根本不使用getAvailablePurchases(),而将最后一次购买存储在设备和服务器上。 如果应用程序被删除或用户移动到新手机,我们在服务器上的最后一次购买仍将与公司用户ID和平台(iOS或Android)相关联。 调用getAvailablePurchases()大约需要一分钟,有时会调用此触发器来触发购买更新的侦听器,以尝试恢复多个购买。 我们修改了这样的流程:

  1. 用户登录设备时:
    a)查看我们的服务器上是否有针对该用户和平台的有效最后一次购买。
    b)如果服务器上没有记录,请查看数据库中是否有本地保存的购买
    c)如果没有或已过期,请显示订阅视图。
    最初,我们调用getAvailablePurchases()并尝试查看上一次购买是否仍然有效。 不知道这是否对其他人有帮助,但是我们不再遇到与此有关的问题。 我们正在作出反应59,这是我们必须应对的另一种痛苦。

我相信我们可以从收据中获得最新的购买。 通过使用exclude-old-transactions:true验证用户的接收,我们可以获得最新的订阅信息(仅适用于自动更新类型)。 我相信我们可以使用这种方法来恢复自动更新的订阅购买。 我不确定这是否是理想的方法。

此页面是否有帮助?
0 / 5 - 0 等级