React-native-iap: purchaseUpdatedListener hanya dipanggil sekali saat aplikasi dimulai, dan tidak pernah memanggil setelah panggilan requestSubscription

Dibuat pada 21 Apr 2020  ·  22Komentar  ·  Sumber: dooboolab/react-native-iap

Versi react-native-IAP

4.4.6

Versi react-native

0.61.5

Platform yang Anda hadapi kesalahan (IOS atau Android atau keduanya?)

ios

Perilaku yang diharapkan

purchaseUpdatedListener dipanggil setiap kali, setelah requestSubscription panggilan

Perilaku sebenarnya

purchaseUpdatedListener hanya dipanggil sekali saat aplikasi dimulai, dan tidak pernah memanggil setelah panggilan requestSubscription

Lingkungan yang diuji (Emulator? Perangkat Nyata?)

Perangkat Nyata

Langkah-langkah untuk mereproduksi perilaku

Ikuti saja readme dan coba minta berlangganan

📱 iOS 🕵️‍♂️ need more investigation 🙏 help wanted

Komentar yang paling membantu

Memiliki masalah yang sama karena saya tidak menambahkan panggilan initConnection() .
README tampaknya baru saja diperbarui dengan bagian tebal di sini:

initConnection() Di iOS, itu hanya akan memanggil metode canMakePayments dan mengembalikan nilai __yang diperlukan agar pendengar berfungsi dengan baik .__

Saya pikir bagian ini "Di iOS, ini hanya akan memanggil canMakePayments" harus dihapus, juga initConnection() harus ditambahkan ke contoh dasar

Saya benar-benar yakin itu opsional karena tidak ada dalam contoh

Menambahkan initConnection() sebelum mendaftarkan pendengar pembelian memperbaiki ini untuk saya, jadi ini mungkin terkait dengan # 1002 dan # 756

Semua 22 komentar

Apakah ada orang lain yang mengalami masalah yang sama? @Strate sudahkah kamu menelepon finishTransaction ?

@hyochan ya, tetapi sebenarnya panggilan ini terjadi setelah aplikasi dimulai ulang

@hyochan Saya sudah mencoba paket expo-in-app-purchase, dan tidak ada masalah seperti ini - semua tampaknya baik-baik saja

@Strate Saya ingin melihat kode Anda. Tidak dapat menemukan kesalahan apa pun sendiri :(

masalah ini benar-benar menyebalkan. Apakah ada versi sebelumnya yang tidak demikian?

Apakah ada orang lain yang mengalami masalah yang sama? @Strate sudahkah kamu menelepon finishTransaction ?

Bagaimana ini mungkin karena pembelian merupakan argumen dalam finishTransaction? Jadi, Anda memerlukan pemroses kejadian untuk mendapatkan argumen agar diteruskan ke finishTransaction.

@Sophrinix finishTransaction diharapkan dipanggil di dalam purchaseUpdatedListener

@hyochan maaf, tapi sepertinya saya tidak memiliki kode sebenarnya sekarang, saya telah beralih ke modul expo-in-app-purchase . Sepertinya @Sophrinix mengalami masalah yang sama.

Btw, tidak ada yang istimewa dalam kode saya: daftarkan pendengar segera setelah aplikasi dimulai, dan cukup ikuti readme.

Ternyata ini regresi.

Jika Anda menggunakan versi berikut, maka semuanya berfungsi:

"react": "16.8.1",
"react-native": "^0.59.10",
"react-native-iap": "4.3.0",

Masalahnya muncul saat Anda mencoba menggunakan react-native-iap 4.4.4 dan versi react-native sebelum 0.60

@Sophrinix Saya baru saja mencoba requestPurchase di sisi saya dan semuanya sepertinya bekerja. Bisakah Anda membagikan beberapa kode Anda?

Selain itu, periksa kembali apakah Anda telah menelepon initConnection . Ini adalah perubahan penting dalam pembaruan terkini yang sekarang perlu dipanggil dalam iOS seperti pada android .

Saya mengonfirmasi bahwa mengembalikan ke 4.3.0 berfungsi. Saya menjadi gila dengan versi terbaru, saya telah melakukan debug selama lebih dari 1 jam mencoba menemukan masalah.

Jika saya boleh menambahkan, 4.3.4 hingga 4.4.3 berfungsi dengan baik, masalah dimulai dengan 4.4.4

Jika saya boleh menambahkan, 4.3.4 hingga 4.4.3 berfungsi dengan baik, masalah dimulai dengan 4.4.4

Sama di sini, Diturunkan dari 4.4.8 ke 4.4.3 dan sekarang berfungsi!

Apakah ada orang lain yang mengalami masalah yang sama? @Strate sudahkah kamu menelepon finishTransaction ?

Saya mengalami masalah yang sama pada 4.4.0 - tidak ada pendengar acara yang dipanggil, termasuk purchaseErrorSubscription .

Baca saja tentang penurunan, saya akan mencobanya ...

Sunting: Ini adalah masalah serius karena:

  • ini mencegah pembelian dikirim untuk pemrosesan server
  • itu mencegah rollback negara ketika seseorang membatalkan pembelian.

Saya juga dapat mengonfirmasi bahwa 4.3.0 berfungsi.

Saya mengalami masalah yang sama selama beberapa hari dengan RN 0.62.2 dan react-native-iap 4.4.8
Saya entah bagaimana melewatkan initConnection() mungkin karena hilang dari contoh di README

Memiliki masalah yang sama di iOS saat meningkatkan ke 4.4.8 yang membuat beberapa langganan tidak selesai. Menurunkan versi ke 4.4.3 menyelesaikan masalah, untuk saat ini. Apakah initConnection () wajib? Doc membuatnya tampak seperti tidak

Memiliki masalah yang sama karena saya tidak menambahkan panggilan initConnection() .
README tampaknya baru saja diperbarui dengan bagian tebal di sini:

initConnection() Di iOS, itu hanya akan memanggil metode canMakePayments dan mengembalikan nilai __yang diperlukan agar pendengar berfungsi dengan baik .__

Saya pikir bagian ini "Di iOS, ini hanya akan memanggil canMakePayments" harus dihapus, juga initConnection() harus ditambahkan ke contoh dasar

Saya benar-benar yakin itu opsional karena tidak ada dalam contoh

Menambahkan initConnection() sebelum mendaftarkan pendengar pembelian memperbaiki ini untuk saya, jadi ini mungkin terkait dengan # 1002 dan # 756

Saya menggunakan 4.4.9 dan masalah yang dijelaskan oleh tiket ini juga terjadi pada saya.
Pendengar hanya dipanggil saat dimulai, tetapi jika saya menyetelnya dan kemudian melakukan pembelian, pendengar tidak dipanggil.
Saya menyelesaikannya dengan berlangganan ke acara asli secara langsung, setelah melihat react-native-iap/index.ts dan mencari tahu itulah yang terjadi secara internal.
Ini dapat dilakukan kapan saja dan akan terus berlanjut. (Pastikan itu dilakukan hanya sekali)

import { NativeModules, NativeEventEmitter } from 'react-native';
import { Observable } from 'rxjs/Observable';

const purchaseEvent = Observable.fromEvent(
  new NativeEventEmitter(NativeModules.RNIapIos),
  'purchase-updated'
);
const purchaseSubscription = purchaseEvent.subscribe((transactionData) => {
  // Trigger server receipt validation here...
});
const errorEvent = Observable.fromEvent(
  new NativeEventEmitter(NativeModules.RNIapIos),
  'purchase-error'
);
const errorSubscription = errorEvent.subscribe((errorData) => {
  // Handle errors here...
});

Banyak orang mengalami kesalahan karena initConnection() tidak ada dalam kode contoh README. Saya telah menambahkannya di sini: # 1088, tetapi jika ada yang dapat memeriksa ulang kode saya, itu akan dihargai. (Saya masih belum memiliki kode saya berfungsi penuh jadi saya tidak terlalu yakin tentang itu ...)

Saya juga mengalami masalah ini di v5.1.1. initConnection tidak menyelesaikannya. Callback pendengar tidak pernah dipicu pada purchaseUpdate. Bekerja dengan baik di android sekalipun. Solusi saya adalah menggunakan Observables seperti yang dilakukan @mrozanski .

import React, { useContext, useEffect, useState } from 'react';
import { Alert, EmitterSubscription, Platform, NativeEventEmitter,
    NativeModules } from 'react-native';
import { connect } from 'react-redux';
import RNIap, {
    InAppPurchase,
    PurchaseError,
    SubscriptionPurchase,
    purchaseErrorListener,
    purchaseUpdatedListener,
} from 'react-native-iap';
import { Observable, Subscription } from 'rxjs';

const RNIAPEvent = new NativeEventEmitter(NativeModules.RNIapIos);
const purchaseObservable = new Observable((subscriber) => {
    RNIAPEvent.addListener('purchase-updated', (event) => {
        subscriber.next(event);
    })
})

const RNIAPErrorEvent = new NativeEventEmitter(NativeModules.RNIapIos);
const purchaseErrorObservable = new Observable((subscriber) => {
    RNIAPErrorEvent.addListener('purchase-error', (event) => {
        subscriber.next(event);
    })
})


const Wrapper = ({ ...props }) => {

    let purchaseUpdateSubscription: EmitterSubscription | Subscription | null = null;
    let purchaseErrorSubscription: EmitterSubscription | Subscription | null = null;

    const validateTransaction = async (purchase: SubscriptionPurchase) => {    
        return new Promise(async (resolve) => {
              //resolve(validationResponseFromYourBackend)
        }
    }

    const handleSubEvent = async (purchase: InAppPurchase | SubscriptionPurchase) => {
        const receipt = purchase.transactionReceipt;
        const purchaseToken = purchase.purchaseToken
        if (receipt) {
            try {
                const result = await validateTransaction(purchase);
                if (result.status === 200) {
                    RNIap.acknowledgePurchaseAndroid(purchaseToken).then(() => {
                        RNIap.finishTransaction(purchase, false)
                        .then(() => giveYourUserValue())
                        .catch((e) => {
                            //
                        })
                    })
                }
            } catch (err) {
                //
            }
        }
    }


    useEffect(() => {
        RNIap.initConnection()
            .then(() => {
                RNIap.flushFailedPurchasesCachedAsPendingAndroid().catch(() => {
                    // exception
                    })
                .then(() => {
                    if (Platform.OS === 'ios') {
                        //Documented implementation has issues purchaseUpdatedListener callback
                        purchaseUpdateSubscription = purchaseObservable.subscribe((purchase) => {
                            console.log('purchase observable', purchase)
                            handleSubEvent(purchase);
                        });

                        purchaseErrorSubscription = purchaseErrorObservable.subscribe((error) => {
                            console.log('purchaseErrorListener', error);
                        })

                    } else {
                        //for android use the documented method. Callbacks work.
                        purchaseUpdateSubscription = purchaseUpdatedListener(
                            (purchase: InAppPurchase | SubscriptionPurchase) => {
                                handleSubEvent(purchase);
                            }

                        );
                        purchaseErrorSubscription = purchaseErrorListener(
                            (error: PurchaseError) => {
                               console.log('purchaseErrorListener', error);
                            },
                        );
                    }

                })
            })
        return () => {
              // clear your listeners
             //eg if Subscription purchaseErrorSubscription.unsubscribe() 
            //eg if EmitterSubscription purchaseErrorSubscription.remove() 
        }
    }, []);

    return (
        <InAppSubContext.Provider
            value={{
                someValueYouWantPassedDown: 'theValue'
            }}
        >
            {props.children}
        </InAppSubContext.Provider>
    )
}

const mapState = (state) => ({ someProps: 'yeah' });

const InAppSubscriptionManager = connect(mapState)(Wrapper);

export default InAppSubscriptionManager;

Anda sekarang dapat menggunakan ini untuk menggabungkan aplikasi Anda dengan App.tsx :


import InAppSubscriptionManager from './path/to/inAppSubscriptionManager';
const App = () => {

    return (
        <Provider store={store}>
                <InAppSubscriptionManager>

                    <AppNavigator />

                </InAppSubscriptionManager>
        </Provider>
    );
}

export default App;

Senang bisa membantu. Kami memiliki ini dalam produksi sejak Juni.
Itu memang berubah dari Observable ke ini di beberapa titik (kami tidak menggunakan skrip tipe)

      const purchaseEvent = new NativeEventEmitter(NativeModules.RNIapIos);
      const subscription = purchaseEvent.addListener(
        'purchase-updated',
        transactionData => {
          console.log('IAP-LOG purchase-updated');
          dispatch(validateRecepit(transactionData));
        }
      );
      const errorSubscription = purchaseEvent.addListener(
        'purchase-error',
        data => {
          crashlytics().log(`Purchase error ${JSON.stringify(data)}`);
          console.log('IAP-LOG purchase-error', data);
        }
      );
    };
Apakah halaman ini membantu?
0 / 5 - 0 peringkat