react-native-splash-screen: Some firebase functionality not working with react-native-splash-screen

I have used react-native-firebase in my react native project[android platform] to show the app notification. With this library i am able to show the notification when the app is in the foreground/background/closed state.

According to the react native firebase documentation the onNotificationOpened should be triggered when the app is opened by the notification tap. However this is not happening in my case, the onNotificationOpened method is never called and getInitialNotification method always gets a null value.

I am also using react-native-splash-screen library to display the splashscreen.

Here’s my code from App.js >> componentDidMount()

firebase.messaging().requestPermission()
            .then(() => {

                const myAppChannel = new firebase.notifications.Android.Channel('my-channel',
                    'my Channel', firebase.notifications.Android.Importance.Max)
                    .setDescription('my channel');
                firebase.notifications().android.createChannel(myAppChannel);


                this.messageListener = firebase.messaging().onMessage((message) => {

                    const {title, body} = message.data;
                    const notificationDisplay = new firebase.notifications.Notification()
                        .setNotificationId('notificationId')
                        .setTitle(title)
                        .setBody(body)
                        .setData({
                            key1: 'value1',
                            key2: 'value2',
                        }).setSubtitle('notification')
                        .setSound('default');
                    notificationDisplay
                        .android.setChannelId('my-channel')
                        .android.setSmallIcon('ic_launcher')
                        .android.setAutoCancel(true).android.setPriority(firebase.notifications.Android.Priority.High);
                        firebase.notifications().displayNotification(notificationDisplay);
                });


                this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen: NotificationOpen) => {
                    //never gets called
                    console.log('onNotificationOpened was triggered on notification taped');

                });

            })
            .catch(error => {
                // User has rejected permissions
                console.log("user rejected");
                console.log(error);
            });

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:name=".MainApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
        <service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>
        <service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/default_notification_channel_id" />

        <activity
            android:name=".SplashActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".MainActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
            android:exported="true"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:windowSoftInputMode="adjustResize" />
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

NOTE: Problem was caused by the react-native-splash-screen library, I was able to fix this after removing the react-native-splash-screen library from the android project. However i am still not sure how i can make this work when using the react-native-splash-screen.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 10
  • Comments: 29

Most upvoted comments

EDITED: Do not use this library. It is not maintained and has problems like this one. Apparently on iOS it can cause unexpected FCM token expiration even! Do not use this library. Use https://github.com/zoontek/react-native-bootsplash/

Original below:

I used the above snippets to fix getInitialNotification but I still wasn’t seeing my onNotification and onNotificationOpened handlers firing with the splash screen / firebase combo and the two Activity style advocated in most splash screen tutorials

There was something missing with the onNewIntent() data passing between the two activities and singleTop activitiy mode etc. Rather than continue to hack at it I tried to simplify

So I did the splash screen in a single Activity, and it worked well. I get the initial theme loading immediately, then the layout inflates and shows the screen, then it goes away in javascript when I call hide, and all my notification handlers from react-native-firebase work correctly.

This is in MainActivity.java:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Use SplashTheme in AndroidManifest.xml for MainActivity, themes loads before layouts inflate
        setTheme(R.style.AppTheme); // Now set the theme from Splash to App before setContentView
        setContentView(R.layout.launch_screen); // Then inflate the new view
        SplashScreen.show(this); // Now show the splash screen. Hide it later in JS
        super.onCreate(savedInstanceState);
    }

AndroidManifest.xml snippet

      <activity
        android:name=".MainActivity"
        android:theme="@style/LaunchTheme"
        android:launchMode="singleTop"
        android:label="@string/app_name"
        android:exported="true">
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
      </activity>

styles.xml

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
    </style>
    <style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@drawable/background_launch</item>
    </style>

This issue should be closed now I think. There’s no problem with splash screen, it’s just subtle to use it correctly

We ran into the same problem recently. From your AndroidManifest.xml I suspect you followed the same guide that we did!

For us, the lack of notifications when cold launched had nothing to do with react-native-splash-screen. The problem lay in the SplashActivity added to the manifest at the same time.

SplashActivity is launched first as the main entry point and receives the notification data. You must pass them along as intent “extras” when starting MainActivity.

This is the code for our SplashActivity.java which is working as expected for us with FCM:

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class SplashActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtras(getIntent().getExtras());  // Pass along FCM messages/notifications etc.
        startActivity(intent);
        finish();
    }
}

@rickgrundy thank you for this snippet! I forced to change for my project for extra check to not-null:

package com.chatium.app;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class SplashActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);

        // Pass along FCM messages/notifications etc.
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            intent.putExtras(extras);
        }
        
        startActivity(intent);
        finish();
    }
}

Thanks for the solution. In my case, this is working , my callbacks are called but the data (body) is undefined. I have following code in my mainactivity.java - @override public void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); }

Also, my launchMode is singleTask for both SplashActivity and MainActivity.

The data is coming through perfectly for us; everything is working exactly the same as it was before we added the splash screen.

Our manifest has android:launchMode="singleTask" for MainActivity, and nothing explicit (so presumably whatever the default is) for SplashActivity.

We have no special intent handling code in MainActivity.java. This is the entire class:

public class MainActivity extends ReactActivity {
    @Override
    protected String getMainComponentName() {
        return "OurAppName";
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        SplashScreen.show(this);
        super.onCreate(savedInstanceState);
    }
}

@mikehardy I am not using react-native-splash-screen . I am doing it by basic flow but getInitialNotification() giving null everytime

@Anujmoglix stop using this dead library. Switch to react-native-bootsplash https://github.com/zoontek/react-native-bootsplash/

Do not use this library. It is not maintained and has problems like this one. Use https://github.com/zoontek/react-native-bootsplash/

I used the above snippets to fix getInitialNotification but I still wasn’t seeing my onNotification and onNotificationOpened handlers firing with the splash screen / firebase combo and the two Activity style advocated in most splash screen tutorials

There was something missing with the onNewIntent() data passing between the two activities and singleTop activitiy mode etc. Rather than continue to hack at it I tried to simplify

So I did the splash screen in a single Activity, and it worked well. I get the initial theme loading immediately, then the layout inflates and shows the screen, then it goes away in javascript when I call hide, and all my notification handlers from react-native-firebase work correctly.

This is in MainActivity.java:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Use SplashTheme in AndroidManifest.xml for MainActivity, themes loads before layouts inflate
        setTheme(R.style.AppTheme); // Now set the theme from Splash to App before setContentView
        setContentView(R.layout.launch_screen); // Then inflate the new view
        SplashScreen.show(this); // Now show the splash screen. Hide it later in JS
        super.onCreate(savedInstanceState);
    }

AndroidManifest.xml snippet

      <activity
        android:name=".MainActivity"
        android:theme="@style/LaunchTheme"
        android:launchMode="singleTop"
        android:label="@string/app_name"
        android:exported="true">
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
      </activity>

styles.xml

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
    </style>
    <style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowBackground">@drawable/background_launch</item>
    </style>

This issue should be closed now I think. There’s no problem with splash screen, it’s just subtle to use it correctly

Dear @mikehardy Your solution works perfectly. However at the beginning I got an error saying background_launch does not exist, which was true. (I had launch_screen). I renamed it to launch_screen and everything works.

@rickgrundy Thanks for the code snippet, I got mine working by adding android:launchMode=“singleTop” for both Main and Splash activity and passing current intent extras (notification data) to new intent and that to Main Activity