react-native-push-notification / ios

React Native Push Notification API for iOS.
MIT License
739 stars 284 forks source link

Not able to receive notification in any app state. #284

Open ArchanaSharma95 opened 3 years ago

ArchanaSharma95 commented 3 years ago

I have update my react native firebase to v6 and used this package to show notification on iOS. But I am not receiving notification in any of the state: foreground, background and when app is in closed state.

This is my AppDelegate.h file::

#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UNUserNotificationCenter.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>

@property (nonatomic, strong) UIWindow *window;

@end

AppDelegate.m file::

#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

#import <ReactNativeNavigation/ReactNativeNavigation.h>
#import "RNSplashScreen.h"
#import <Firebase.h>
#import "SDImageCodersManager.h"
#import <SDWebImageWebPCoder/SDImageWebPCoder.h>
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
    [ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions];
//    if ([FIRApp defaultApp] == nil) {
        [FIRApp configure];
//    }
    // show splash screen
    [RNSplashScreen show];
    // Register support for WebP images.
    [SDImageCodersManager.sharedManager addCoder:SDImageWebPCoder.sharedCoder];
    // Define UNUserNotificationCenter
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    return YES;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
 [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event. You must call the completion handler after handling the remote notification.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
 [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}

@end

After this inside my App.js file I called this function inside constructor::

NotificationService.getInstance().initializeNotificationServiceForIOS();

I have created one service file where I have written the notification logic for android and iOS. Push notifications working fine on android but not getting in case of iOS. This is a code inside my service file for iOS.

 import { Alert } from "react-native";
 import PushNotification from 'react-native-push-notification';
 import messaging from '@react-native-firebase/messaging';
 import NotificationHandler from './NotificationHandler';
 import PushNotificationIOS from '@react-native-community/push-notification-ios';
 import AsyncStorage from '@react-native-community/async-storage';
 //constants
 import { androidNotificationChannelId, isIOS } from '../../constants';
 import LocalStorageKeys from '../../constants/LocalStorageKeys';

 export default class NotificationService {
     /**
      * @returns {NotificationService}
      */
     static getInstance() {
         if (NotificationService.myInstance == null) {
             NotificationService.myInstance = new NotificationService();
         }
         return this.myInstance;
     }

     initializeNotificationServiceForIOS() {
         PushNotificationIOS.addEventListener('register', this.onRegistered);
         PushNotificationIOS.addEventListener('registrationError', this.onRegistrationError);
         PushNotificationIOS.addEventListener('notification', this.onRemoteNotification);
         PushNotificationIOS.addEventListener('localNotification', this.onLocalNotification);
         PushNotificationIOS.requestPermissions().then(
             (data) => {
                 console.log('PushNotificationIOS.requestPermissions', data);
             },
             (data) => {
                 console.log('PushNotificationIOS.requestPermissions failed', data);
             },
         );
    }

     onRegistered = (deviceToken) => {
         console.log("ios deviceToken", deviceToken)
         AsyncStorage.setItem(LocalStorageKeys.DEVICE_TOKEN, deviceToken);
      };

     onRegistrationError = (error) => {
         Alert.alert(
            'Failed To Register For Remote Push',
            `Error (${error.code}): ${error.message}`,
            [
              {
                 text: 'Dismiss',
                 onPress: null,
              },
            ],
         );
      };

     onRemoteNotification = (notification) => {
         const isClicked = notification.getData().userInteraction === 1;

         const result = `
            Title:  ${notification.getTitle()};\n
            Subtitle:  ${notification.getSubtitle()};\n
            Message: ${notification.getMessage()};\n
            badge: ${notification.getBadgeCount()};\n
            sound: ${notification.getSound()};\n
            category: ${notification.getCategory()};\n
            content-available: ${notification.getContentAvailable()};\n
            Notification is clicked: ${String(isClicked)}.`;

         if (notification.getTitle() == undefined) {
            Alert.alert('Silent push notification Received', result, [
              {
                 text: 'Send local push',
                 onPress: sendLocalNotification,
              },
            ]);
         } else {
            Alert.alert('Push Notification Received', result, [
              {
                 text: 'Dismiss',
                 onPress: null,
              },
            ]);
         }
     };

     onLocalNotification = (notification) => {
         const isClicked = notification.getData().userInteraction === 1;

         Alert.alert(
            'Local Notification Received',
            `Alert title:  ${notification.getTitle()},
            Alert subtitle:  ${notification.getSubtitle()},
            Alert message:  ${notification.getMessage()},
            Badge: ${notification.getBadgeCount()},
            Sound: ${notification.getSound()},
            Thread Id:  ${notification.getThreadID()},
            Action Id:  ${notification.getActionIdentifier()},
            User Text:  ${notification.getUserText()},
            Notification is clicked: ${String(isClicked)}.`,
            [
              {
                 text: 'Dismiss',
                 onPress: null,
              },
            ],
         );
     };
 }

I have added console inside the "onRemoteNotification" and "onLocalNotification" but nothing happened after sending notification. Also I rechecked the apns certificate and other setting on firebase, this is completed still i am not getting any test sms from firebase and also on any event while sending notification remotely.

Please help and suggest something because I stuck here.

rawatnaresh commented 3 years ago

@ArchanaSharma95 were you able to solve this? I'm having the same problem.

Aexonic-Abhishek commented 3 years ago

I'm also getting same issue. For me remote notifications are not working but local notifications are working

Kamill90 commented 3 years ago

Same here. I have added certificates to firebase - development, and production. Local and scheduled notifications working fine. Remote on android also works. Only ios is silent codebase here https://github.com/Kamill90/RoadTripApp-RN

rawatnaresh commented 3 years ago

I guess you need to complete these additional steps for iOS

https://rnfirebase.io/messaging/usage/ios-setup

qpooqp777 commented 2 years ago

me too,IOS Remote not work,android is Ok , i do complete these additional steps for iOS. help!

my Project https://github.com/qpooqp777/bhctest01

plz help,thx.

rawatnaresh commented 2 years ago

@qpooqp777 you need to complete these additional steps for notifications to work on iOS https://rnfirebase.io/messaging/usage/ios-setup

Also sometimes notifications sent from firebase dashboard doesn't appear. Try sending notifications from postman https://firebase.google.com/docs/cloud-messaging/http-server-ref

qpooqp777 commented 2 years ago

@rawatnaresh thanks.I reused RN-FCM, getFCMtoken, but not using apsnToken, I can receive messages normally.

aravi365 commented 2 years ago

@qpooqp777 can you please share the fullcode to get token using fcm? do we need to initialse firebase core package??

jmada commented 1 month ago

@qpooqp777, @aravi365, did you guys find the solution for this? how did you do it?