j3k0 / cordova-plugin-purchase

In-App Purchase for Cordova on iOS, Android and Windows
https://purchase.cordova.fovea.cc
1.3k stars 537 forks source link

Unregister handlers #813

Closed francoisduchemin closed 5 years ago

francoisduchemin commented 5 years ago

I am working on an Ionic app with a very simple "Remove ads" in-app purchase. One of the pages displays the products along with a "Buy now" button.

Everything is working fine the first time the page is loaded: the updated callback is called and the products are displayed. But if the user navigates to another page, and then comes back, the handlers are not called anymore (productUpdated is not called in the code below).

Here's what I'm doing:

ngOnInit() {
  const product: IAPProductOptions = { ... };
  this.store.register(product);
  this.store.when(this.productId).updated(this.productUpdated);
  this.store.refresh();
}

ngOnDestroy() {
  this.store.off(this.productUpdated);
}

private productUpdated: IAPQueryCallback = (product: IAPProduct) => {
  this.loader.dismiss();
  this.products.push(product); // updates the UI
  ...
};

Do I need to unregister something else? Unregister the product somehow? Am I forgetting something?

j3k0 commented 5 years ago

I'm assuming ngOnInit() is called when the view is shown and not when the app starts. You have to register the products and handlers as soon as the app starts and never unregister them again. One thing to keep in mind: in-app purchase events can occur at any time, outside of your control.

This have been discussed time and time again: an order can be initiated from another device / from the AppStore itself, and have to be finalized when your app starts (or gets back from background).

That is Apple/Google requirements, it's stated black and white on their respective documentations.

j3k0 commented 5 years ago

Also, productUpdated is gonna be called way more than 1 time... So if you're pushing the product each time, it might get ugly ;-)

j3k0 commented 5 years ago

And just a doubt: do you need the fat arrow => for productUpdated (not sure if you're not messing up the value of this with this)?

francoisduchemin commented 5 years ago

Thank you so much for your fast reply @j3k0 !!

j3k0 commented 5 years ago

I have to call this.store.refresh() when the app starts (just after registering the product and the handlers), right?

Right.

Will this.store.refresh() not trigger a popup (especially on iOS devices) to ask the user to enter his credentials when the app is starting?

Nope, except if you're having an expired subscription and your receipt validator doesn't make use of the latest_receipt_info field (which isn't your case).

francoisduchemin commented 5 years ago

Perfect I'm going to change my implementation accordingly! Thanks a lot. I guess you can close the "issue" (which was not really an issue, more a mistake from my side)

j3k0 commented 5 years ago

Good luck!

wongwideweb commented 4 years ago

Perfect I'm going to change my implementation accordingly! Thanks a lot. I guess you can close the "issue" (which was not really an issue, more a mistake from my side)

Hi there Franco, can you post the final solution to your code here?