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

[ANDROID] Subscribed user treated as unsubscribed on app startup #1087

Closed samirame closed 11 months ago

samirame commented 4 years ago

system info

Plugin:
cordova-plugin-purchase     :10.2.0
@ionic-native/in-app-purchase-2 : 5.27.0

Ionic:

   Ionic CLI                     : 6.5.0
   Ionic Framework               : @ionic/angular 5.2.1
   @angular-devkit/build-angular : 0.901.8
   @angular-devkit/schematics    : 8.3.26
   @angular/cli                  : 9.1.8
   @ionic/angular-toolkit        : 2.2.0

Capacitor:

   Capacitor CLI   : 2.2.0
   @capacitor/core : 2.2.0

System:

   NodeJS : v13.5.0 
   npm    : 6.13.4
   OS     : macOS Catalina

Device  : Android v 10

Observed behavior

Hi, I am using this Plugin with Capacitor to provide subscription to the users. The app uses AdMobs to display ads to unsubscribed users. Upon subscription, the ads will be removed.

The problem I am facing is that when the app launches for a subscribed user, the state of product is not yet known and the product will go through a sequence of "not-owned" states till it finally reaches the "owned" state. This causes the app to show the Ad for a moment and then removes it as the product is eventually detected to be in owned state.

Now my question is, how can I make sure that I am taking actions only after the product state is stabilised. I have noticed that the plugin triggers a “refresh-finished” event at this point. Is there a way to be notified of this point?

[store.js] DEBUG: store.trigger -> triggering action refresh-finished

I first thought of using store().refresh().finished(fn) as mentioned in the docs. However, I was not able to use it as it is not recognised/supported by the IONIC InAppPurchase2 plugin so far. (https://github.com/ionic-team/ionic-native/issues/3480) Is there an alternative way?

Here is a more detailed explanation on how I have implemented Ad-free upon subscription feature in my app:

To implements this I have defined a BehaviorSubject called “showAd” in my in-app-purchase service, which emits the value false for showAd if the product is in owned state, and true if otherwise, as shown below

this.store.when('product').updated((p: IAPProduct) => {
  if (p.owned) {
  this._showAd.next(false);
} else {
        this._showAd.next(true);
}
});

In the app startup I have subscribed to the showAd subject and based on its value I will display or remove the banner ad.

ghost commented 3 years ago

Im experiencing a similar issue. It seems to work fine on iOS i.e. seems to quickly detect if no subscription on initial load and therefore no flicker between states (user has subscribed or not). However, on Android there seems to be a delay, then a moment later user subscription is detected. I guess I was wondering what is the recommended approach of detecting a valid subscription on initial registering in such a way that it would avoid possible flickering between modes. Basically assume user is subscribed until told otherwise by one of the store events.

Lpn01 commented 3 years ago

Hi. I know I'm a little late to the party, but hopefully, this helps someone. What I'm doing is that when the user subscribes, I'm saving his/her subscription data in localstorage so that on each startup, I instantly know if the user has a subscription or not. After each startup, I'm checking with my server (that uses the Fovea validator to keep track of subscriptions) and if my server replies that the subscription is expired, I'm informing the user, removing the benefits and removing the data from localstorage. I'm not sure you can always rely on calling the store to check, the connection might be slow (especially over mobile data), the store might be slow to reply or temporary unavailable, etc.

sksk008 commented 3 years ago

as suggested here

(this.store.refresh() as any).finished(() => { console.log('Refresh Store done'); if(this.store.get(productId).owned) //hideads else //show purchase dialogue });

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.