react-native-splash-screen icon indicating copy to clipboard operation
react-native-splash-screen copied to clipboard

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

Open selvesandev opened this issue 5 years ago • 29 comments

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.

selvesandev avatar Aug 20 '18 07:08 selvesandev

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 avatar Sep 15 '18 07:09 rickgrundy

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();
    }
}

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.

awdhootlele avatar Oct 09 '18 09:10 awdhootlele

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);
    }
}

rickgrundy avatar Oct 09 '18 22:10 rickgrundy

@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

awdhootlele avatar Oct 10 '18 05:10 awdhootlele

@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();
    }
}

Strate avatar Oct 29 '18 11:10 Strate

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

mikehardy avatar Jun 15 '19 23:06 mikehardy

I can also confirm this for react-native-push-notification

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

I can also confirm this working for react-native-push-notification

nathantaal avatar Aug 30 '19 12:08 nathantaal

The above examples are all Android related. I am having issues using getInitialNotification() from FCM returning null on iOS. Using react-native-splash-screen 3.2.0, react-native 0.59.9 and react-native-firebase 5.5.6, any clues?

For me android is just fine.

ramonvermeulen avatar Nov 11 '19 11:11 ramonvermeulen

No clues per se, but creating a minimal reproduction should be possible? Then you'd have a basis to troubleshoot. I just recently checked this in my app on ios using the three you mention, and it worked for me so I can't reproduce

mikehardy avatar Nov 11 '19 13:11 mikehardy

I have an similar issue. All my remote notifications, not launch/open the app when i tap on notification. Not even in background, foreground or killed.

I've followed the sugestion of @mikehardy to use SplashScreen as single activity, but not works at all for me.

joaom182 avatar Feb 26 '20 20:02 joaom182

@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 it's worked for me

prakashsaran avatar Apr 15 '20 08:04 prakashsaran

I met this issue on IOS, anyone have a solution for IOS side ?

daithinh2401 avatar Apr 28 '20 07:04 daithinh2401

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.

ghasemikasra39 avatar Jun 06 '20 08:06 ghasemikasra39

@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 it's worked for me

May I ask where exactly you put this code?

skizzo avatar Jun 09 '20 17:06 skizzo

For any one having this issue on iOS, please try replace [RNSplashScreen show]; with [RNSplashScreen showSplash:@"LaunchScreen" inRootView:rootView];

bpetrified avatar Jun 18 '20 09:06 bpetrified

I fixed this issue by adding [RNSplashScreen showSplash:@"LaunchScreen" inRootView:rootView]; in the function below. the other function that was suggested in the readme doesn't have access to rootView

- (RCTBridge *)initializeReactNativeApp
{
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:self.launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil];
  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  [RNSplashScreen showSplash:@"LaunchScreen" inRootView:rootView]; // <------------------------added this

  return bridge;
}

EdmundMai avatar Jun 25 '20 04:06 EdmundMai

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

mikehardy avatar Jul 06 '20 15:07 mikehardy

woho..... worked for me.

jyotishman avatar Aug 05 '20 07:08 jyotishman

I got an error saying background_launch does not exist,

Anujmoglix avatar Aug 09 '20 07:08 Anujmoglix

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

mikehardy avatar Aug 09 '20 15:08 mikehardy

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

Anujmoglix avatar Aug 15 '20 15:08 Anujmoglix

@mikehardy I'm not using React Native Splash Screen either and having the same issues as @Anujmoglix, I believe react-native-bootsplash has a ton of bugs as well even with push notifications that Expensify ran into, so I'm not sure it's a good alternative at all.

pateljoel avatar Dec 15 '21 04:12 pateljoel

React native boosplash has literally 4 bugs total logged. 2 are aesthetic Nothing like what was happening here. There's one iOS bug there about a hide too soon but it doesn't have a repro yet not sure there is any other library maintained as well as that

mikehardy avatar Dec 15 '21 04:12 mikehardy

@pateljoel I stlil await any substantiation for your assertion bootsplash has a "ton of bugs" so far sounds like smoke, no fire. Please back your assertions.

mikehardy avatar Dec 20 '21 12:12 mikehardy

@mikehardy I moved away from both of these libraries as the bugs were untenable for me and I ended up writing my own for my needs.

Last I checked over at react-native-bootsplash & Expensify they are still having issues with it even in production, so it is a no go for me even if it is 'literally 4 bugs'.

pateljoel avatar Jan 05 '22 07:01 pateljoel

Vague assertions, no reproducible bug reports 🤔

mikehardy avatar Jan 05 '22 11:01 mikehardy

I should react splashActivity.java?

I don't have it... please help me

jackimatin avatar Apr 13 '22 09:04 jackimatin

I should react splashActivity.java?

I don't have it... please help me

@jackimatin i have the same problem did you solve it ?

ferasabufares avatar Jun 10 '23 08:06 ferasabufares

Relacing react-native-splash-screen by react-native-bootsplash is not fixing all the issues: https://github.com/wix/react-native-notifications/issues/958

TwistedMinda avatar Sep 14 '23 12:09 TwistedMinda