Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] purchaseUpdatedListener firing only once, not on every subscription transaction #1122

Closed
mzablockifm opened this issue Sep 21, 2020 · 37 comments
Assignees
Labels
🤖 android Related to android 🙏 help wanted Extra attention is needed Stale 🧪 test Issue or pr related to testing

Comments

@mzablockifm
Copy link

Version of react-native-iap

"react-native-iap": "4.5.4",

Version of react-native

"react-native": "0.61.4",

Platforms you faced the error (IOS or Android or both?)

Android, not tested on iOS

Expected behavior

purchaseUpdatedListener firing every time purchase is received

Actual behavior

purchaseUpdatedListener firing only once for first recipt, then nothing happens

Tested environment (Emulator? Real Device?)

Real device, run in dev env with test google account (subscription recurring every 5 minutes - email is incoming but receipt is not).

Simplified code I am using:

import React from 'react';
import { Text, View, TouchableOpacity, Alert } from 'react-native';
import RNIap, {
  purchaseUpdatedListener,
  purchaseErrorListener,
} from 'react-native-iap';

import { SpinnerOverlay } from '../components/SpinnerOverlay';

import { itemSkus } from '../config/in-app';
import { validateRecipt } from '../utils/validateRecipt';
import { logger } from '../utils/logger';

export class SubscriptionScreenInner extends React.Component {
  purchaseUpdateSubscription = null;
  purchaseErrorSubscription = null;

  constructor(props) {
    super(props);
    this.state = {
      products: [],
      productsLoaded: false,
      isProcessing: false
    };
  }

  componentDidMount = async () => {
    try {
      if (itemSkus) {
        await RNIap.initConnection();
        await RNIap.flushFailedPurchasesCachedAsPendingAndroid();
        const products = await RNIap.getSubscriptions(itemSkus);
        this.setState({ products, productsLoaded: true });

        this.purchaseUpdateSubscription = purchaseUpdatedListener(
          async (purchase) => {
            try {
              const receipt = purchase.transactionReceipt;
              if (receipt) {
                const validate = await validateRecipt(purchase);

                if (validate) {
                  await RNIap.finishTransaction(purchase, false);
                  this.props.fetchUserProfile();
                  this.resetScreenState();
                  Alert.alert('receipt validated', 'cool');
                }
              }
            } catch (error) {
              this.resetScreenState();
              logger('Validate recipt error', error);
            }
          }
        );

        this.purchaseErrorSubscription = purchaseErrorListener((error) => {
          this.resetScreenState();
          logger('Purchase error during loading', error);
        });
      }
    } catch (error) {
      logger('Store prroducts error', error);
    }
  };

  componentWillUnmount() {
    if (this.purchaseUpdateSubscription) {
      this.purchaseUpdateSubscription.remove();
    }

    if (this.purchaseErrorSubscription) {
      this.purchaseErrorSubscription.remove();
    }

    RNIap.endConnection();
  }

  requestSubscription = async (sku) => {
    this.setState({ isProcessing: true }, async () => {
      await RNIap.requestSubscription(sku);
    });
  };

  resetScreenState = () => {
    this.setState({ isProcessing: false });
  };

  render() {
    const { products, productsLoaded, isProcessing } = this.state;

    if (!productsLoaded || isProcessing) {
      return (
        <View>
          <SpinnerOverlay />
        </View>
      );
    }

    return (
      <View>
        <View>
          <View>
            <View>
              <Text>Buy monthly subscription</Text>
            </View>

            <View>
              <TouchableOpacity onPress={() => this.requestSubscription(products[0].productId)}>
                <Text>Buy</Text>
              </TouchableOpacity>
            </View>
          </View>
        </View>
      </View>
    );
  }
}
@mzablockifm
Copy link
Author

I upgraded React Native to 0.63.2 but it haven't helped.

@mzablockifm
Copy link
Author

After bumping react-native-iap to 4.6.3 no change.

@mwerder
Copy link

mwerder commented Oct 16, 2020

I have exactly the same issue, used to be on 4.4.9, bumped to 4.6.3 and still occurs
Were you able to fix it or did you figure out a workaround?

@mzablockifm
Copy link
Author

Unfortunately I don't have solution for this.

@hyochan hyochan added 🤖 android Related to android 🙏 help wanted Extra attention is needed labels Oct 26, 2020
@hyochan
Copy link
Member

hyochan commented Oct 26, 2020

This is very strange. Are you saying that you attempt to purchase again after the first purchase, the purchaseUpdatedListener is not firing? I've tested this earlier and it should keep firing until you kill the listener.

@hyochan
Copy link
Member

hyochan commented Oct 26, 2020

Oh, I see. You are having a problem with the next subscription event. Let me test this out and come back.

@hyochan hyochan added the 🧪 test Issue or pr related to testing label Oct 26, 2020
@hyochan hyochan self-assigned this Oct 26, 2020
@hyochan hyochan added 📱 iOS Related to iOS and removed 📱 iOS Related to iOS labels Oct 26, 2020
@mj-iosdev
Copy link

We are facing the same issue, I was using 4.4.9 and tried to downgrade and upgrade to latest 5.1.1 but result is still same. Only getting event first time.

@Kalesberg
Copy link

any solution to this?

@mzablockifm
Copy link
Author

As a temporary solution I save first receipt from subscription event and validate it on each application initialization - it works, but I tested it only for Android.

@Kalesberg
Copy link

Hi, @hyochan
Any idea when this will be resolved?

thanks

@hyochan
Copy link
Member

hyochan commented Oct 31, 2020

Thanks for the reminder! I'll test this out tomorrow.

@Kalesberg
Copy link

@hyochan
I know you are still working on the issue, just wanted to know about the next patch date for this issue as our entire team is waiting for this one.
Thank you

@hyochan
Copy link
Member

hyochan commented Nov 3, 2020

@Kalesberg I will definitely try out this week and share updates. However, this library is used by many others and the implementation on purchaseUpdatedListner hasn't been changed since then. I might have to make a reproducible example firstly. I'll try this week.

@hyochan
Copy link
Member

hyochan commented Nov 3, 2020

Related for iOS in #1160

@Kalesberg
Copy link

@hyochan
Appreciate it!!

@hyochan
Copy link
Member

hyochan commented Nov 3, 2020

@Kalesberg Could you kindly verify that android.test.purchased also fires multiple times?

@Kalesberg
Copy link

@hyochan will do that!

@Kalesberg
Copy link

@hyochan
Our product is only for subscription base, so android.test.purchased cannot best testified.
So I tried to use your demo app in this library and added test.sub1 but I was not able to get any product with it
Screenshot 2020-11-04 at 6 53 06 PM

@hyochan
Copy link
Member

hyochan commented Nov 4, 2020

@Kalesberg Could you put android logcat where it triggers purchaseUpdatedListener?

Please tell me what's coming in billingResult and purchases.

@Kalesberg
Copy link

@hyochan , hope it helps
really looking forward to this patch release

@hyochan
Copy link
Member

hyochan commented Nov 7, 2020

I am trying to look into this now. By the way can you give me better file format? rtf file is hard to open in my env which is chromeos. You may also send me an email (hyo@dooboolab.com) if you think it has privacy issue.

@hyochan
Copy link
Member

hyochan commented Nov 7, 2020

@Kalesberg
Copy link

@hyochan
Does this mean there is nothing wrong with this plugin?

@Kalesberg
Copy link

the iOS version works fine but just the android phones are problematic

@hyochan
Copy link
Member

hyochan commented Nov 8, 2020

We are just finding out the problem. However, following the logcat you've provided, it looks like to me that the acknowledgePurchase which is finishTransaction didn't work properly since the purchase was on the air. I've shared the stackoverflow which also talks about the similar situation.

@Kalesberg
Copy link

@hyochan
the problem persists even in test subscription mode which should always succeed

@Kalesberg
Copy link

@hyochan , any updates on the plugin?

@mzablockifm
Copy link
Author

Current state (with newest version of iap) for ios: app receives first receipt and then when staying in foreground it won't receive next receipt. After closing app and opening it again it gets all pending receipts.

@nishanttatva
Copy link

@hyochan
For android, the purchaseUpdatedListener is called for first time when subscription is bought, and it is verified successfully by my backend server. But the auto-renewal events are not getting received in the app. I tried keeping in foreground, background and also kill and relaunch app. Still purchaseUpdatedListener is not called.

@nishanttatva
Copy link

Could you put android logcat where it triggers purchaseUpdatedListener?

Please tell me what's coming in billingResult and purchases.

@hyochan added the logs, the purchase listener is called with, but purchases size is 0

@kesha-antonov
Copy link

Hi guys,
did you solve this?

@andresesfm
Copy link
Collaborator

Hello, can somebody check if this is still an issue in 6.1.0 or newer? I have the feeling this was caused by a race condition in these two statements: c44e0fc#diff-00c325bb857787738381a0cfd47136178fec851cdd5c2c300346067214e62678R128-R132 (just a hunch)

@pafry7
Copy link
Contributor

pafry7 commented Sep 8, 2021

We end up using Real-time developer notifications for handling renewals and cancellations. I think that many people that are coming from web background, assume that every renewal will trigger the listener.

@stale
Copy link

stale bot commented Apr 18, 2022

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale label Apr 18, 2022
@herbertvuijk
Copy link

Having this issue still in 2022. Unfortunately I dont see any thing in this thread that explains what is happening. On IOS its working fine and I'm receiving the purchase updates, on Android I only receive the first receipt and then the monthly renewal receipts never arrives to IAP.purchaseUpdatedListener

@andresesfm
Copy link
Collaborator

on iOS you get the renewal updates on the client.
on Android, your backaned subscribes to changes (server to server updates)

@herbertvuijk
Copy link

Ok, thanks that explains a lot. Will look into the server 2 server part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 android Related to android 🙏 help wanted Extra attention is needed Stale 🧪 test Issue or pr related to testing
Projects
None yet
Development

No branches or pull requests

10 participants