zo0r / react-native-push-notification

React Native Local and Remote Notifications
MIT License
6.76k stars 2.05k forks source link

how to get notification when app is open(foreground)?? #919

Closed ydv0121 closed 3 years ago

ydv0121 commented 5 years ago

i can't understand how to get notification when app is open.. only get notification when app is in background(closed).

and yes, notification pushed from the backend(NodeJs)

please help..i want notification in both condition when app is background stat or foreground stat

muhammadhaseebsohail commented 5 years ago

anyone figure this out? i am also facing same issue

ydv0121 commented 5 years ago

no stil not..i am converting remote notification to local notification when remote notification get.

muhammadhaseebsohail commented 5 years ago

but localnotification are also not showing when i am using the application, it only shows in background can you show me your code sir? it will be a great help.

n1ru4l commented 5 years ago

IDK about android but for ios: https://stackoverflow.com/a/14872263/4202031

If the application is running in the foreground, iOS won't show a notification banner/alert. That's by design. You have to write some code to deal with the situation of your app receiving a notification while it is in the foreground. You should show the notification in the most appropriate way (for example, adding a badge number to a UITabBar icon, simulating a Notification Center banner, etc.).

n1ru4l commented 5 years ago

@muhammadhaseebsohail @ydv0121

Update:

I got it working by using UNUserNotificationCenterDelegate

This solution only works for remote notifications. I give you no guarantee that it will work with local notifications.

Preview: https://sendvid.com/28rcl468

Tutorial:

  1. Adjust AppDelegate.h
#import <UIKit/UIKit.h>
+ #import <UserNotifications/UNUserNotificationCenter.h>
+ #import <UserNotifications/UNNotification.h>
+ #import <UserNotifications/UNNotificationRequest.h>
+ #import <UserNotifications/UNNotificationContent.h>

- @interface AppDelegate : UIResponder <UIApplicationDelegate>
+ @interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>

@property (nonatomic, strong) UIWindow *window;

@end
  1. Adjust AppDelegate.m
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  ...
+  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
+  center.delegate = self;
}

 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
-  [RCTPushNotificationManager didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
+  NSMutableDictionary* userInfoCopy = [userInfo mutableCopy];
+  userInfoCopy[@"userHasInteracted"] = @YES;

+  [RCTPushNotificationManager didReceiveRemoteNotification:[NSDictionary dictionaryWithDictionary:userInfoCopy] fetchCompletionHandler:^(UIBackgroundFetchResult result) {
+    if ([userInfoCopy[@"userHasInteracted"] boolValue] == YES) {
+      return;
+    }
+    completionHandler(result);
+  }];
}

+ - (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
+  [RCTPushNotificationManager didReceiveRemoteNotification:notification.request.content.userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
+    completionHandler(UNNotificationPresentationOptionAlert);
+  }];
+}

In the JSCode you can check for the boolean value notification.data.userHasInteracted which will be true if the user started the application with a push notification or pressed on the push notification.

In the latter case you should not be confused. When the notification arrives initially your onNotification handler will be called the first time with the notification without having the (notification.data.userHasInteracted) property. The second time it is called when the user clicks on the notification, this time the same notification will have the notification.data.userHasInteracted set to true.

muhammadhaseebsohail commented 5 years ago

Bingo <3 You are a life saver @n1ru4l .
i was stuck here from the last 2 weeks.

ydv0121 commented 5 years ago

What about android?? How to get notification in android when app is in foreground...?? without using local notification???

timbielawski commented 5 years ago

Hi,

I was experiencing the same issue then noticed a difference in the AndroidManifest.xml config. This fixed it for me

android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm

ydv0121 commented 5 years ago

Hi,

I was experiencing the same issue then noticed a difference in the AndroidManifest.xml config. This fixed it for me

android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm

can you please provide your AndroidMainfest.xml

timbielawski commented 5 years ago

It was this part

` <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm" android:exported="false" >

    </service>`
ydv0121 commented 5 years ago

It was this part

<service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm" android:exported="false" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> </intent-filter> </service>

thank you...let me check...so after put this line..i will get the noification when app is in foreground/open

timbielawski commented 5 years ago

Yeah worked for me

ydv0121 commented 5 years ago

@timbielawski my app is crashing when send notification my AndroidMainfest.xml

`<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.watch">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
 <uses-permission android:name="android.permission.CAMERA" />
 <uses-permission android:name="android.permission.CALL_PHONE" />
 <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
<permission
    android:name="${applicationId}.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

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

  >
    <receiver
        android:name="com.google.android.gms.gcm.GcmReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="${applicationId}" />
        </intent-filter>
    </receiver>

    <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
    <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/>
    <service
        android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>
  <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:windowSoftInputMode="adjustResize"
    android:screenOrientation="portrait" 
    >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
  </activity>
  <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>

`

timbielawski commented 5 years ago

`

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<permission
    android:name="${applicationId}.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>`

` <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" />

<application
  android:name=".MainApplication"
  android:allowBackup="true"
  android:label="@string/app_name"
  android:icon="@mipmap/ic_launcher"
  android:theme="@style/AppTheme"
  android:largeHeap="true">
  <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:screenOrientation="portrait"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:windowSoftInputMode="stateUnspecified|adjustResize"
    android:launchMode="singleTask">
    <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" />
    </intent-filter>
  </activity>
  <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

  <receiver
       android:name="com.google.android.gms.gcm.GcmReceiver"
       android:exported="true"
       android:permission="com.google.android.c2dm.permission.SEND" >
       <intent-filter>
           <action android:name="com.google.android.c2dm.intent.RECEIVE" />
           <category android:name="${applicationId}" />
       </intent-filter>
   </receiver>

   <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
    <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/>
    <service
        android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>

</application>`
ydv0121 commented 5 years ago

app is crashing when receiving notification

timbielawski commented 5 years ago

I am on "react-native-push-notification": "3.1.2",

onNotification: notification => { } called?

muhammadhaseebsohail commented 5 years ago

@n1ru4l in IOS, while i am receving remote notification of chat, everytime, the remote notification also shown in application. the remote notificaiton is also showing in the foreground, is there any way to stop remote notifications and alow only local notifications to show in foreground ? I will be very gratefull for your help.

quynhnguyen68 commented 5 years ago

Hi @n1ru4l , I use your solution, it works (showing the alert) when app in foreground

I got it working by using UNUserNotificationCenterDelegate

Preview: https://sendvid.com/28rcl468

However, it doesn't play sound like it does when app in background. I want to play sound with notification alert, I try this but it doesn't work.

  [RCTPushNotificationManager didReceiveRemoteNotification:notification.request.content.userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
    completionHandler(UNNotificationPresentationOptionAlert);
    completionHandler(UNNotificationPresentationOptionSound);
    completionHandler(UNNotificationPresentationOptionBadge);
  }];

Do you have any solution for this problem. Thank you

muhammadhaseebsohail commented 5 years ago

@quynhnguyen68 can you show your Payload? did you pass sound: "default " in APNS payload?

quynhnguyen68 commented 5 years ago

@quynhnguyen68 can you show your Payload? did you pass sound: "default " in APNS payload?

Yes, I used 'default' @muhammadhaseebsohail

ydv0121 commented 5 years ago

@muhammadhaseebsohail brother how to get notification in foreground in android? from server didn't get onNotification LOG as well

NNprajapati commented 5 years ago

Hi i can not getting local notification in foreground app.

any one is know what is the problem of in my code as bellow:

#import <UserNotifications/UNUserNotificationCenter.h>
#import <UserNotifications/UNNotification.h>
#import <UserNotifications/UNNotificationRequest.h>
#import <UserNotifications/UNNotificationContent.h>
#import <React/RCTPushNotificationManager.h>`

@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self; 
}

 - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
 {
  [RCTPushNotificationManager didRegisterUserNotificationSettings:notificationSettings];
 }

 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
 {
  [RCTPushNotificationManager didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
 }

 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
                                                        fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
 {

     NSMutableDictionary* userInfoCopy = [userInfo mutableCopy];
     userInfoCopy[@"userHasInteracted"] = @YES;

    [RCTPushNotificationManager didReceiveRemoteNotification:[NSDictionary dictionaryWithDictionary:userInfoCopy] fetchCompletionHandler:^(UIBackgroundFetchResult result) {
      if ([userInfoCopy[@"userHasInteracted"] boolValue] == YES) {
        return;
      }
      completionHandler(result);
    }];
 }

 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
 {
    [RCTPushNotificationManager didFailToRegisterForRemoteNotificationsWithError:error];
 }

- (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    [RCTPushNotificationManager didReceiveRemoteNotification:notification.request.content.userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
         completionHandler(UNNotificationPresentationOptionAlert);
    }];
}

In JS file

componentDidMount() {
      PushNotification.configure({
        onNotification: function(notification) {
          console.log( 'NOTIFICATION:', notification );
        },
      });
    }

localNotification() {

      PushNotification.localNotificationSchedule({
        //... You can use all the options from localNotifications
        message: "My Notification Message", // (required)
        date: new Date(Date.now() + (5 * 1000)) // in 5 secs
      });
  }
n1ru4l commented 5 years ago

@NNprajapati Did you know you can format your block code https://help.github.com/articles/creating-and-highlighting-code-blocks/ ?

I am using my example with remote notifications. I do not use local notifications.

n1ru4l commented 5 years ago

@quynhnguyen68 wrote:

However, it doesn't play sound like it does when app in background. I want to play sound with notification alert, I try this but it doesn't work.

No I do not have a solution for this. I do not need a sound when the app is in the foreground.

NNprajapati commented 5 years ago

@NNprajapati Did you know you can format your block code https://help.github.com/articles/creating-and-highlighting-code-blocks/ ?

I am using my example with remote notifications. I do not use local notifications.

Ok thank you, and also thanks for the advice to 'code formate'

icastillejogomez commented 5 years ago

I follow all this steps https://github.com/zo0r/react-native-push-notification/issues/919#issuecomment-439373380 and notifications still works out but I cannot see the notifications when app is in foreground. The notification arrive and onNotification is called. All ok. But I need to set something like displayAlways to control when the notification has to be displayed and when not.

Pleaseeee help!!!

gino8080 commented 5 years ago

@muhammadhaseebsohail @ydv0121

Update:

I got it working by using UNUserNotificationCenterDelegate

This solution only works for remote notifications. I give you no guarantee that it will work with local notifications.

Preview: https://sendvid.com/28rcl468

Tutorial:

  1. Adjust AppDelegate.h
#import <UIKit/UIKit.h>
+ #import <UserNotifications/UNUserNotificationCenter.h>
+ #import <UserNotifications/UNNotification.h>
+ #import <UserNotifications/UNNotificationRequest.h>
+ #import <UserNotifications/UNNotificationContent.h>

- @interface AppDelegate : UIResponder <UIApplicationDelegate>
+ @interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>

@property (nonatomic, strong) UIWindow *window;

@end
  1. Adjust AppDelegate.m
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  ...
+  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
+  center.delegate = self;
}

 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
-  [RCTPushNotificationManager didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
+  NSMutableDictionary* userInfoCopy = [userInfo mutableCopy];
+  userInfoCopy[@"userHasInteracted"] = @YES;

+  [RCTPushNotificationManager didReceiveRemoteNotification:[NSDictionary dictionaryWithDictionary:userInfoCopy] fetchCompletionHandler:^(UIBackgroundFetchResult result) {
+    if ([userInfoCopy[@"userHasInteracted"] boolValue] == YES) {
+      return;
+    }
+    completionHandler(result);
+  }];
}

+ - (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
+  [RCTPushNotificationManager didReceiveRemoteNotification:notification.request.content.userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
+    completionHandler(UNNotificationPresentationOptionAlert);
+  }];
+}

In the JSCode you can check for the boolean value notification.data.userHasInteracted which will be true if the user started the application with a push notification or pressed on the push notification.

In the latter case you should not be confused. When the notification arrives initially your onNotification handler will be called the first time with the notification without having the (notification.data.userHasInteracted) property. The second time it is called when the user clicks on the notification, this time the same notification will have the notification.data.userHasInteracted set to true.

You SAVED my Life!!!!

RediaUa commented 4 years ago

@muhammadhaseebsohail @ydv0121

Update:

I got it working by using UNUserNotificationCenterDelegate

This solution only works for remote notifications. I give you no guarantee that it will work with local notifications.

Preview: https://sendvid.com/28rcl468

Tutorial:

  1. Adjust AppDelegate.h
#import <UIKit/UIKit.h>
+ #import <UserNotifications/UNUserNotificationCenter.h>
+ #import <UserNotifications/UNNotification.h>
+ #import <UserNotifications/UNNotificationRequest.h>
+ #import <UserNotifications/UNNotificationContent.h>

- @interface AppDelegate : UIResponder <UIApplicationDelegate>
+ @interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>

@property (nonatomic, strong) UIWindow *window;

@end
  1. Adjust AppDelegate.m
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  ...
+  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
+  center.delegate = self;
}

 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
-  [RCTPushNotificationManager didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
+  NSMutableDictionary* userInfoCopy = [userInfo mutableCopy];
+  userInfoCopy[@"userHasInteracted"] = @YES;

+  [RCTPushNotificationManager didReceiveRemoteNotification:[NSDictionary dictionaryWithDictionary:userInfoCopy] fetchCompletionHandler:^(UIBackgroundFetchResult result) {
+    if ([userInfoCopy[@"userHasInteracted"] boolValue] == YES) {
+      return;
+    }
+    completionHandler(result);
+  }];
}

+ - (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
+  [RCTPushNotificationManager didReceiveRemoteNotification:notification.request.content.userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
+    completionHandler(UNNotificationPresentationOptionAlert);
+  }];
+}

In the JSCode you can check for the boolean value notification.data.userHasInteracted which will be true if the user started the application with a push notification or pressed on the push notification.

In the latter case you should not be confused. When the notification arrives initially your onNotification handler will be called the first time with the notification without having the (notification.data.userHasInteracted) property. The second time it is called when the user clicks on the notification, this time the same notification will have the notification.data.userHasInteracted set to true.

If app is not running, I get a notification but if a tap on it - onNotification event didn't trigger, and I can't implement navigation :(

github-actions[bot] commented 3 years ago

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