zoontek / react-native-bootsplash

🚀 Show a splash screen during app startup. Hide it when you are ready.
MIT License
3.75k stars 259 forks source link

v3.2.6 Android 30 - when clicking push notification from QUIT hide() is fired too early #289

Closed billnbell closed 2 years ago

billnbell commented 3 years ago

Bug summary

We are using hide in App.tsx wrapped in a useAsyncEffect(). This fires before the code in onCreate fires and we get an error. I wrapped it in a setTimeout() and I think this may work. But what is the best way to do this?

This only happens when the app is stopped/not running and the user clicks a push notification to open the app. What happens is the app Splash screen just sites there and when hide() fires it says it is not initialized.

  useAsyncEffect(async () => {
    log.debug('useAsyncEffect Run from APP');
    try {
      setTimeout(() => {
        RNBootSplash.hide({ fade: true });
      }, 1500);
    } catch (err) {
      log.error('RNBootSplash.hide', err);
    }
  }, []);

In MainActivity I have the following. Question, can we move this earlier to fire on a push notification click?

  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      RNBootSplash.init(R.drawable.bootsplash, MainActivity.this);
  }

Here is my AndroidManifest.xml.

  <queries>
    <intent>
      <action android:name="android.intent.action.VIEW"/>
      <data android:scheme="mailto"/>
    </intent>
  </queries>
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  <uses-permission android:name="android.permission.USE_FINGERPRINT"/>
  <uses-permission android:name="android.permission.USE_BIOMETRIC"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove"/>
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  <!-- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> -->
  <uses-permission android:name="android.permission.VIBRATE"/>
  <application android:name="com.exclusiveresorts.theclub.MainApplication" android:requestLegacyExternalStorage="true" android:usesCleartextTraffic="true" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme">
   <meta-data android:name="com.transistorsoft.locationmanager.license" android:value="ee407893f0efc5697488cfb17bfcb52b3cac99bafade957f4667daa3063f926c"/>
    <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
<!--    <service android:name="com.transistorsoft.locationmanager.service.TrackingService" android:foregroundServiceType="location"/>-->
<!--    <service android:name="com.transistorsoft.locationmanager.service.LocationRequestService" android:foregroundServiceType="location"/>-->
    <activity android:name="com.exclusiveresorts.theclub.MainActivity"
      android:label="@string/app_name"
      android:screenOrientation="portrait"
      android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
      android:launchMode="singleTask"
      android:windowSoftInputMode="adjustResize"
      android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.SENDTO" />
        <data android:scheme="mailto" />
      </intent-filter>
    </activity>
    <activity
        android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
        android:launchMode="singleTask"
        android:theme="@style/BootTheme"
        android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="theclub" />
      </intent-filter>
    </activity>
  </application>
</manifest>

Library version

3.2.6

Environment info

React Native.

Steps to reproduce

  1. Send PROD push notification
  2. Click it
  3. Screen does not go away and gives error.

Reproducible sample code

N/A
zoontek commented 3 years ago

This only happens when the app is stopped/not running and the user clicks a push notification to open the app. What happens is the app Splash screen just sites there and when hide() fires it says it is not initialized.

But is is visible? If not, just catch and ignore the promise rejection

billnbell commented 3 years ago

It is not visible yet. As you can see I am doing a try/catch.

When the react-native code hits RNBootSplash.hide({ fade: true }); the Android process has not yet hit, RNBootSplash.init(R.drawable.bootsplash, MainActivity.this); So it does not see visibility yet, since RNBootSplash is not loaded, and the catch() is fired.

But in about 50 ms, the RNBootSplash.init(R.drawable.bootsplash, MainActivity.this); is hit, and the bootstrap runs. Then react-native never knows about it, and the screen never hides.

This only happens on Push Notification clicking when the app is CLOSED/QUIT/Shutdown in Android. Adding the setTimeout to hide works perfectly, but I don't like it. Is there a way to synchronously get the
RNBootSplash.init(R.drawable.bootsplash, MainActivity.this); to fire before react native starts?

zoontek commented 3 years ago

Update to v4.x, it should fix the issue.

billnbell commented 3 years ago

OK I like 4.x since it moves to one Activity. However by setting 31 (Android 12) I am having several errors in the build. It seems the issue in most packages is not having android:exported="true" - is there a way to patch <Activities and add android:exported="true" as I build? That will get me a lot farther.

billnbell commented 3 years ago

I will try this:

<receiver android:name="<name_of_the_entry>"
                android:exported="false or true"
                tools:node="merge" />
zoontek commented 3 years ago

@billnbell First, check if the libraries have an update for compatibility with Android 12. If this cannot be done, check this: https://stackoverflow.com/a/68866812/5529224

zoontek commented 2 years ago

@billnbell Did you succeeded? Does the issue still exists?

billnbell commented 2 years ago

I installed it. Will do more testing.

viLeeKorn commented 2 years ago

@zoontek is it possible to add custom style for 3.2.6 version for android ? (currently version of react native 0.64)

billnbell commented 2 years ago

It works in latest version.

zoontek commented 2 years ago

Cool! I'm closing this then