React-native-iap: getAvailablePurchases gibt jedes Mal ein anderes Array zurück

Erstellt am 9. Aug. 2019  ·  13Kommentare  ·  Quelle: dooboolab/react-native-iap

Version von react-native-iap

3.3.9 (erlebt dies aber auch in 3.0.0 und früher)

Version von React-Native

0,59,9

Plattformen, auf denen Sie den Fehler hatten (IOS oder Android oder beides?)

iOS (nicht auf Android getestet)

Erwartetes Verhalten

Jedes Mal, wenn ich getAvailablePurchases aufrufe, dasselbe Array
Jedes Mal die gleiche Array-Länge

Tatsächliches Verhalten

Jedes Mal, wenn ich getAvailablePurchases aufrufe, ein anderes Array
Unterschiedliche Array-Länge jedes Mal, wenn ich getAvailablePurchases

Getestete Umgebung (Emulator? Reales Gerät?)

Echtes Gerät

Schritte zum Reproduzieren des Verhaltens

Ich denke, dies ist nur bei vielen Transaktionen sichtbar, kann dies aber nicht bestätigen. Mein Sandbox-Konto hat mehr als 50 Transaktionen.

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;
}

Wenn ich mit dem obigen Code auf "Kauf wiederherstellen" drücke, erhalte ich jedes Mal andere Protokolle:

Drücken Sie 6 Mal auf "Kauf wiederherstellen", und warten Sie zwischendurch, bis die Ergebnisse eingehen:

// 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

Ich würde erwarten, dass das Array immer das gleiche ist, oder? Was passiert hier?

Das Ergebnis von getAvailablePurchases() ist jedes Mal anders, wenn ich es ausführe

📱 iOS 🙏 help wanted 🚶🏻 stale

Hilfreichster Kommentar

Ich habe auch eine Schleife für alle Transaktionen ausgeführt und konnte sie mit finishTransactionIOS nicht entfernen. Meine Transaktionen verlängern Abonnements automatisch.

Alle 13 Kommentare

Ich sehe das auch. Das wirklich Gefährliche daran ist, dass möglicherweise die letzte gültige Quittung nicht in den Ergebnissen enthalten ist.

Wenn man sich den Code dieses Moduls ansieht, sieht es ehrlich gesagt wie ein Problem auf Apples Seite aus, da dieses Modul praktisch nur das durchläuft, was restoreCompletedTransactions() zurückgibt

Ich frage mich, ob getPurchaseHistory() eine gute Alternative für Abonnements ist. Ich benutze das derzeit als Alternative, da ich so zuverlässige Ergebnisse bekomme. Ich habe keine anderen Einkäufe in meiner App, nur Abonnements.

Wie in den iap-Dokumenten zu diesem Paket angegeben, handelt es sich bei getAvailablePurchases() um Verbrauchsmaterialien. Ein Abonnement ist kein "Verbrauchsmaterial" oder "Nichtverbrauchsmaterial". Es ist ein "automatisch erneuerbares Abonnement". Also sollte getPurchaseHistory() reichen?

Screenshot 2019-08-16 at 18 11 13

Ich fand, dass getPurchaseHistory () auch unterschiedliche Array-Längen ergab. Es schien, als ob die Häufigkeit der Anfragen dies bewirkte. Am Ende stellte sich heraus, dass dies für uns nicht wirklich wichtig war. Sobald einer der Transaktionsbelege zur Validierung gesendet wurde, wurden alle Belege von Apple im Array latest_receipt_info , was für uns alles war.

Ich habe das gleiche Problem (weiß nicht, ob es sich um einen Sandbox-Modusfehler handelt). Wenn ich die Apple-ID innerhalb eines realen Geräts wechsle, wird der mit einem anderen Konto getätigte Kauf zurückgegeben.

Ex:
1 - Ich habe mit dem Konto [email protected] einen Kauf
2 - Die Apple-ID wurde auf [email protected] geändert
3 - getAvailablePurchases gibt die Transaktions-ID des mit dem Konto Kaufs zurück

Ein weiteres Problem, das ich festgestellt habe, ist, dass beim Wiederherstellen des Geräts (Zurücksetzen auf die Werkseinstellungen) beide Methoden getPurchaseHistory() und getAvailablePurchases zufällige Ergebnisse liefern

Die Antwort von Apple für die Wiederherstellung eines Kaufs lautet:

"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."

Es wurde ein Thema in den Apple Developer Forums zu den unterschiedlichen Ergebnissen von restoreCompletedTransactions wie bereits von @ ssg-luke erwähnt.

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

Vielleicht hängt das zusammen:

Anscheinend beziehen Sie sich auf einen Benutzer mit vielen Transaktionen, für die die App noch nicht finishTransaction aufgerufen hat.
https://forums.developer.apple.com/thread/115242#thread -post-355444

Ich hatte andere Sandbox-Konten auf demselben Gerät. Könnte es also sein, dass die Transaktionen verschiedener Konten auf demselben Gerät nur durcheinander sind und überhaupt nicht "abgeschlossen" werden?

Ich habe jedoch eine Schleife für alle Transaktionen ausgeführt und finishTransactionIOS allen getAvailablePurchases() ... Vielleicht, weil ich bereits auf einem neueren Sandbox-Konto bin und die Transaktionen von einem älteren Sandbox-Konto stammen?

Könnte auch erklären, was @fcandiani erlebt.

Ich fand, dass getPurchaseHistory () auch unterschiedliche Array-Längen ergab. Es schien, als ob die Häufigkeit der Anfragen dies bewirkte. Am Ende stellte sich heraus, dass dies für uns nicht wirklich wichtig war. Sobald einer der Transaktionsbelege zur Validierung gesendet wurde, wurden alle Belege von Apple im Array "last_receipt_info" zurückgegeben, was für uns alles war.

Danke für die Info @ ssg-luke, ich werde das gleiche tun.

Ich habe auch eine Schleife für alle Transaktionen ausgeführt und konnte sie mit finishTransactionIOS nicht entfernen. Meine Transaktionen verlängern Abonnements automatisch.

Fast gleich. Ich habe ein Problem erstellt, aber beschlossen, alle Informationen hierher zu stellen, um anderen zu helfen, das Problem und die Lösung zu finden.

Version von react-native-iap

3.5.9

Version von React-Native

0,60,5

Plattformen, auf denen Sie den Fehler hatten (IOS oder Android oder beides?)

iOS

  • Der gleiche Code funktioniert perfekt auf Android, das bereits in Produktion ist

Erwartetes Verhalten

Einmal abonnierter Benutzer , getAvailablePurchases sollte nur einen Kauf zurückgeben

Tatsächliches Verhalten

getAvailablePurchases gibt mehr als einen Kauf zurück,

Getestete Umgebung (Emulator? Reales Gerät?)

Echtes Gerät mit frischem Sandbox-Account.

Schritte zum Reproduzieren des Verhaltens

  • Erstellen Sie einen Sandbox-Testbenutzer unter https://appstoreconnect.apple.com/access/testers
  • Projekt auf xcode erstellen und ausführen
  • Rufen Sie getAvailablePurchases und geben Sie keine Käufe zurück (wie erwartet).
  • Abonnieren Sie ein Produkt
  • Mein purchaseUpdatedListener heißt und ich nenne RNIap.finishTransactionIOS(subscription.transactionId); , das nur undefined zurückgibt (wie erwartet, denke ich).
  • Rufen Sie getAvailablePurchases und geben Sie einen Kauf zurück (wie erwartet).
  • App neu laden
  • Rufen Sie getAvailablePurchases und geben Sie zwei Einkäufe mit jeweils unterschiedlichen 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...."
}
  • Laden Sie die App erneut
  • Rufen Sie getAvailablePurchases und geben Sie drei Einkäufe mit jeweils unterschiedlichen transactionId (nicht identisch mit dem vorherigen Ergebnis):
{
   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..."
}
  • Laden Sie die App erneut
  • Rufen Sie getAvailablePurchases und geben Sie vier Einkäufe mit jeweils unterschiedlichen transactionId (nicht das gleiche wie im vorherigen Ergebnis) ...

Dies scheint nicht das richtige Verhalten zu sein, was ich in den Dokumenten gelesen habe und was unter Android passiert.

Ich freue mich über jede Hilfe.

getAvaialblePurchases () gibt mehr als 150 Ergebnisse auf meinem Sandbox-Testkonto zurück. Ich habe mich entschieden, getAvailablePurchases () überhaupt nicht zu verwenden und nur den letzten Kauf auf dem Gerät und auch auf dem Server zu speichern. Wenn die App gelöscht oder der Benutzer auf ein neues Telefon verschoben wird, haben wir immer noch den letzten Kauf auf unserem Server, der an die Benutzer-ID und -Plattform unseres Unternehmens (iOS oder Android) gebunden ist. Das Aufrufen von getAvailablePurchases () dauert fast eine Minute und manchmal das Aufrufen dieses auslösenden Kauf-aktualisierten Listeners, der versucht, mehrere Käufe wiederherzustellen. Wir haben unseren Ablauf folgendermaßen geändert:
1) Wenn sich der Benutzer am Gerät anmeldet:
a) Überprüfen Sie, ob auf unserem Server ein gültiger letzter Kauf für den Benutzer und die Plattform vorliegt.
b) Wenn auf dem Server kein Datensatz vorhanden ist, prüfen Sie, ob in der Datenbank ein lokal gespeicherter Kauf vorhanden ist
c) Wenn es keine gibt oder eine abgelaufen ist, zeigen Sie die Abonnementansicht an.
Anfangs haben wir getAvailablePurchases () aufgerufen und versucht, festzustellen, ob der letzte Kauf noch gültig war. Ich bin mir nicht sicher, ob dies anderen hilft, aber wir haben keine Probleme mehr damit. Wir reagieren auf 59 und das ist ein weiterer Schmerz, mit dem wir uns befassen müssen.

@ramakula und was ist, wenn der Benutzer sein Abonnement

So wie Sie es gesagt haben, behalten Sie das Abonnement bis zum Enddatum in Ihrer Datenbank und "sehen", dass der Kauf nicht mehr verfügbar ist.

Hey, es sieht so aus, als ob in letzter Zeit keine Aktivitäten zu diesem Thema stattgefunden haben. Wurde das Problem behoben oder erfordert es immer noch die Aufmerksamkeit der Community? Dieses Problem kann geschlossen werden, wenn keine weitere Aktivität auftritt. Sie können diese Ausgabe auch als "Zur Diskussion" oder "Gute erste Ausgabe" bezeichnen, und ich werde sie offen lassen. Vielen Dank für Ihre Beiträge.

Schließen dieses Problems nach längerer Inaktivität. Wenn dieses Problem in der neuesten Version noch vorhanden ist, können Sie ein neues Problem mit aktuellen Informationen erstellen.

getAvaialblePurchases () gibt mehr als 150 Ergebnisse auf meinem Sandbox-Testkonto zurück. Ich habe mich entschieden, getAvailablePurchases () überhaupt nicht zu verwenden und nur den letzten Kauf auf dem Gerät und auch auf dem Server zu speichern. Wenn die App gelöscht oder der Benutzer auf ein neues Telefon verschoben wird, haben wir immer noch den letzten Kauf auf unserem Server, der an die Benutzer-ID und -Plattform unseres Unternehmens (iOS oder Android) gebunden ist. Das Aufrufen von getAvailablePurchases () dauert fast eine Minute und manchmal das Aufrufen dieses auslösenden Kauf-aktualisierten Listeners, der versucht, mehrere Käufe wiederherzustellen. Wir haben unseren Ablauf folgendermaßen geändert:

  1. Wenn sich der Benutzer am Gerät anmeldet:
    a) Überprüfen Sie, ob auf unserem Server ein gültiger letzter Kauf für den Benutzer und die Plattform vorliegt.
    b) Wenn auf dem Server kein Datensatz vorhanden ist, prüfen Sie, ob in der Datenbank ein lokal gespeicherter Kauf vorhanden ist
    c) Wenn es keine gibt oder eine abgelaufen ist, zeigen Sie die Abonnementansicht an.
    Anfangs haben wir getAvailablePurchases () aufgerufen und versucht, festzustellen, ob der letzte Kauf noch gültig war. Ich bin mir nicht sicher, ob dies anderen hilft, aber wir haben keine Probleme mehr damit. Wir reagieren auf 59 und das ist ein weiterer Schmerz, mit dem wir uns befassen müssen.

Ich glaube, wir können die neuesten Einkäufe von der Quittung erhalten. Durch Überprüfen des Empfangs eines Benutzers mit Ausschluss alter Transaktionen: true können wir die neuesten Abonnementinformationen abrufen (nur für automatisch erneuerbare Typen). Ich glaube, wir können diese Methode verwenden, um automatisch erneuerbare Abonnementkäufe wiederherzustellen. Ich bin mir nicht sicher, ob dies eine ideale Methode ist.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

chetstone picture chetstone  ·  4Kommentare

ramondelmondo picture ramondelmondo  ·  4Kommentare

safciplak picture safciplak  ·  3Kommentare

MacMillan13 picture MacMillan13  ·  3Kommentare

coldfins picture coldfins  ·  3Kommentare