KjellConnelly / react-native-rate

Send your app users to Apple App Store, Google Play, Amazon, or other using the newest APIs
635 stars 100 forks source link

value of success is always true when I restart the app #75

Closed Youn-ha closed 3 years ago

Youn-ha commented 3 years ago

Hello, thank you so much for making this great library. I have some question to ask.

While testing your package in iOS development mode, I used preferInApp: true, openAppStoreIfInAppFails: false options. I used this code in my 'Home' Screen, so as user get into the 'Home' screen, SKStoreReviewController works. So I can see in-app-review popup in my app, instead of directly opening the store externally.

스크린샷 2020-12-04 오후 6 06 19

But the problem is, even though user doesn't click 'submit' button, I found out that value of success returns as true. Below is my code.

// Home.jsx

const showInAppReview = setTimeout(() => {
  const options = {
    AppleAppID: '0000000000',
    GooglePackageName: 'com.example',
    preferredAndroidMarket: AndroidMarket.Google,
    preferInApp: true,
    openAppStoreIfInAppFails: false,
    inAppDelay: 5.0,
  };

  Rate.rate(options, (success) => {
    console.log('1 =====> ', success);
    if (success) {
      console.log('2 =====> ', success);
    }
  });
}, 5000);

I used setTimeout, so I get console.logs 5 seconds after I reach 'Home' screen. console log if I completely close the app, and restart the app

1 =====> true
2 =====> true

console log when I click 'Not Now' or 'Cancel' in in-app-review popup, and shake my device to reload (I'm testing with actual device linked by USB cable)

// (setTimeout 5 secs + inAppDelay 5 secs = 10 secs)

1 =====> false

So I checked out react-native-rate/ios/RNRate.m file, and found out that there are 4 cases that this callback emits true.


  1. when preferInApp is false
  2. preferInApp is true, but SKStoreReviewController is unavailable
  3. if there is a new window (Appstore expected)
  4. inAppDelay time is over, but there's no user action. And Also, openAppStoreIfInAppFails is true


As I mentioned above, I used preferInApp: true, openAppStoreIfInAppFails: false options, so number 1 and 4 are not my case.

In-app review popup showed off, and appstore didn't open also. So number 2 is not my case too.

I didn't click submit button, so appstore didn't open. The number of windows didn't change. So probably number 3 is not my case too...?

I'm pretty sure number 1 and 4 are not my case, but not very certain of number 2 and 3. Maybe I'm misunderstanding this package, or maybe there are some side effects in my code..?

KjellConnelly commented 3 years ago

Hey @Youn-ha , thanks for asking the question. It's been over a year since I actually added anything myself to this library, so this is what I think is the problem...

When the library first opens the in-app dialogue, a new window is created. The library then looks for this new window when it returns the promise. But due to the way Apple setup this controller, the window is actually never removed from memory, even after all is said and done. So even an hour later, the library will see that there is still 1 more window somewhere in memory than when the library first ran its code.

This is a little hack I created. It doesn't work perfectly, but it's a way around the poorly developed controller that Apple created (their API has no callbacks, which is why I had to look for windows).

Youn-ha commented 3 years ago

Thank you for your response :)

My misunderstanding : New window is created even when in-app dialogue opens - I thought new window is created only when appstore opens externally... So it's normal operation that true value is returned when in-app dialogue is open, is it right?

I wonder what your recommendation is, because my purpose was to make users not see any more review requests after they once submit a review. At first, I thought (=misunderstood) that callback returns true value if user clicks submit button, and if user doesn't, callback would return false. And I thought that if user clicks submit button, appstore page would open externally. (I couldn't test the actual action of 'submit' button because it is disabled in test environment) I searched about this a bit more, and found out that if 'submit' button clicked, review comment popup opens in-app, not externally. (like captured image below)

스크린샷 2020-12-08 오후 3 00 47

Below is my code.

// Home.jsx

const isAlreadyRate = await AsyncStorage.getItem('isAlreadyRate');

if (!isAlreadyRate) {
  const showInAppReview = setTimeout(() => {
    const options = {
      AppleAppID: '0000000000',
      GooglePackageName: 'com.example',
      preferredAndroidMarket: AndroidMarket.Google,
      preferInApp: true,
      openAppStoreIfInAppFails: false,
      inAppDelay: 5.0,
    };

    Rate.rate(options, (success) => {
      if (success) {
        AsyncStorage.setItem('isAlreadyRate', 'true');
      }
    });
  }, 5000);
}

I know that it's unavilable to know whether user actually clicked submit button in in-app dialogue or not, so I guess there's no way to achieve this. Once in-app dialogue opens, callback emits true, so value of isAlreadyRate would be true. Am I understanding right?

KjellConnelly commented 3 years ago

That is correct. There is no way to know for sure using in-app rating. The only way I can think of, of improving your chances of knowing if they reviewed or not, is asking the user to review first using your own UI. This could be a button, or a pop up, and/or have some sort of incentive attached. I know you're technically not supposed to give tangible incentives such as coins for a game, but you can always explain that reviews increase your user base, which in turn increases your revenue, which thus incentivizes you to create new updates, as opposed to putting time into other projects.

One way to make sure you aren't over spamming them is to check your app version number. Write some logic so that the in-app dialog cannot be shown more than once during a single version. Or maybe save the date it was last successfully shown. The thing about the in-app dialogue is that it is only supposed to be shown 3x per year per user maximum.

Youn-ha commented 3 years ago

As your suggestion, I'd better show a popup that simply explains about reviewing and link to in-app dialog (with cancel button also). Thank you so much!!

I was already aware of this - it is only supposed to be shown 3x per year per user maximum - but our planning team asked me to show in-app rating once per 5 login. I thought this could might cause over spamming as you mentioned. By the way this condition - the in-app dialog cannot be shown more than once during a single version - seems so nice! I'll ask them about adding this condition too.

Thank you again for your detailed response. Hope you have a nice day! I'm closing this issue. :)