question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

iOS Receiving Push Notification's only after close/reopen app.

See original GitHub issue

I’m dealing with this problem since 2 days ago. When I install and open app at first time, allow notification’s permission and check that I’ve received APNS Token and Token Firebase, everything looks fine but, when I send a notification via PostMan FCM API and using my Token FCM, it didn’t receive any notification. Surprisedly, when I close and reopen its and resend notification via FCM API, theses notifications arrives quickly… Did somebody deal with this situation?..

Edit (17/09/2020): I tested this app with notifications on iPhone 5s and iPad Air (iOS 12.4.8) and it works fine at first launch, but it doesn’t at iPhone 6s (iOS 12.4.8), iPhone 7 Plus , iPhone XR (iOS +13). I don’t understand what happens.

Edit2 (18/09/2020): Today I updated my dependencies: “react-native-push-notification” to “^5.1.1”, “@react-native-firebase/app” to “^8.4.3” and “@react-native-firebase/messaging” to “^7.8.6”, and now iPhone 5s and iPad Air (iOS 12.4.8) don’t receive nothing at first launch 😦

I’m using (17/09/2020)

"react-native": "0.63.2",
"react-native-push-notification": "^5.1.0",
"@react-native-community/push-notification-ios": "^1.5.0",
"@react-native-firebase/app": "^8.4.1",
"@react-native-firebase/messaging": "^7.8.4",

This is App.js


import React, {
  useEffect,
  useState
} from 'react';
import { Platform, Alert, AppState} from 'react-native'
import { StyleProvider } from 'native-base';
import {
  writeDebug 
} from './src/functions/LoggerService'

import Home from './src/Home';
import getTheme from './src/theme/components';
import variables from './src/theme/variables/commonColor'; 
import NofiticationManagerFCM from './src/functions/NotificationManager';
import NotificationHub from './src/functions/NotificationHub';
import {
  configureDevice,
  requireRPIdentity
} from './src/functions/ConfigDevice';
import LocalNotificationService from './src/functions/NotificationDialog';
import RNBootSplash from "react-native-bootsplash";
import PushNotificationIOS from '@react-native-community/push-notification-ios';
import { write } from 'fs';

let onLoad = false;

const App: React.FC = () => {
  const [onNotificationRecieved, setNofiticationRecieved] = useState(
    false,
  );
  const [notificationBehaviour, setNotificationBehaviour] = useState(
    '',
  );
 
  const [permissions, setPermissions] = useState({});

  useEffect(() => {
    PushNotificationIOS.addEventListener('notification', onRemoteNotification);
  });

  const onRemoteNotification = (notification) => {
    if(Platform.OS == 'ios' &&(typeof notification.getData) === 'function')
    {
        const isClicked = notification.getData().userInteraction === 1
        Alert.alert('es '+ isClicked,JSON.stringify(notification));
        if (isClicked) {
            // Navigate user to another screen
        } else {
            // Do something else with push notification
        }
    }
    else {
      Alert.alert('es ',JSON.stringify(notification));
    }
  };

  useEffect(() => { 
    onLoad = false;
    async function init (){
      let tokenAccess = await requireRPIdentity();
      if(!tokenAccess)
        Alert.alert("Token de Acceso RP", "No se pudo recuperar el token.");
      await configureDevice(); 
      NofiticationManagerFCM.requestOnlyUserPermission().then(async (auth)=>{ 
        writeDebug("RegistroRemoto con ",auth.toString());
        await NofiticationManagerFCM.registerAppWithFCM(auth);
        await NofiticationManagerFCM.registerFCM(onRegister, onNoti, onOpenNoti);
        LocalNotificationService.configure(onOpenNoti); 
      }); 
  
      function onRegister(token) {
      }
  
      function onNoti(remoteMessage) {
        if(AppState.currentState !=='background'){
          LocalNotificationService.showNotification(remoteMessage); 
        }
        NotificationHub.syncNotification(remoteMessage, 2);
      }
  
      async function onOpenNoti(noti) { 
        await NotificationHub.syncNotification(noti, 3);
      }

      return;
    }

    if(!onLoad){ 
      onLoad=true;
      init().then((x)=>{
      }).catch((err)=>{
        writeDebug('Error en Init',err);
      }).finally(()=>{ 
        RNBootSplash.hide({ duration: 250 });
      }); 
    }
    
    return () => {
      LocalNotificationService.unregister();
    };
  }, [notificationBehaviour]);
   
  return (
    <>
      <StyleProvider style={getTheme(variables)}>
        <Home/>
      </StyleProvider>
    </>
  );
};

export default App;

NotificationDialog.js


import PushNotification from 'react-native-push-notification';
import {
  Platform
} from 'react-native';
import
NotificationHub
from './NotificationHub';
import PushNotificationIOS from '@react-native-community/push-notification-ios';
import {
    writeDebug 
} from './LoggerService'

class LocalNotificationService {
  configure = (onOpened) => {
    let parent = this;
    PushNotification.configure({
      onRegister: function (token) { 
        writeDebug('Token Generado',token);
      },
      onNotification: async function (notification) {
        if(Platform.OS === 'ios' && notification ){ 
          try{
            writeDebug('Noti abierta Foreground iOS',notification); 
            await onOpened(notification); 
            notification.finish(PushNotificationIOS.FetchResult.NoData); 
          }
          catch(err){
            writeDebug('Error al abrir Notificación',err);
          }
        }
      },
      // IOS Properties
      permissions: {
        alert: true,
        badge: true,
        sound: true,
      },

      popInitialNotification: true,
      requestPermissions: true,
    });
    this.recoveringNotification();
  };

  recoveringNotification = ()=>{ 
    if (Platform.OS === 'ios'){ 
      PushNotificationIOS.getInitialNotification().then((remoteMessage)=>{ 
        if (remoteMessage) {
          let newNoti = {};
          if(typeof remoteMessage.foreground == 'boolean' && !remoteMessage.foreground){
            newNoti.data = remoteMessage;
            newNoti.notification = remoteMessage;
          }
          else {
            newNoti = remoteMessage;
          }
          NotificationHub.syncNotification(newNoti, 3);
          writeDebug('Noti abierta Background iOS',newNoti);  
        }
      });
    }
    else {
      PushNotification.popInitialNotification((remoteMessage) => {
        if (remoteMessage) { 
          let newNoti = {};
          if(typeof remoteMessage.foreground == 'boolean' && !remoteMessage.foreground){
            newNoti.data = remoteMessage;
            newNoti.notification = remoteMessage;
          }
          else {
            newNoti = remoteMessage;
          }
          NotificationHub.syncNotification(newNoti, 3);
          writeDebug('Noti abierta Background Android',newNoti); 
        } 
      });
    }
  }

  unregister = () => {
    PushNotification.unregister();
  };

  showNotification = (obj) => {
    PushNotification.localNotification({
      ...this.buildAndroidNotification(2),
      ...this.buildIOSNotification(2),
      title: obj.notification.title,
      message: obj.notification.body,
      body: obj.notification.body,
      channelId: 'rn-push-notification-channel-id-4-default-300',
      messageId: obj.messageId,
      vibrate: true,
      vibration: 300,
      priority: 'max',
      importance: 'max',
    });
  };

  buildAndroidNotification = (id) => {
    return {
      id: id,
      largeIcon: 'ic_launcher_round',
      largeIconUrl: 'ic_launcher_round',
      smallIcon: 'ic_stat_onesignal_default', 
      vibrate: true,
      vibration: 300,
    };
  };

  buildIOSNotification = (id) => {
    return {
      alertAction: 'view', 
      userInfo: {
        id: id,
      },
    };
  };

  cancelAllNotifications = () => {
    if (Platform.OS === 'ios') {
      PushNotificationIOS.cancelAllLocalNotifications();
    } else {
      PushNotification.cancelAllLocalNotifications();
    }
  };

  removeDeliveredNotificationById = (notificationId) => {
    PushNotification.cancelLocalNotifications({
      id: `${notificationId}`
    });
  };
}

export default new LocalNotificationService();

NotificationManager.js

import messaging, {firebase} from '@react-native-firebase/messaging'; 
import {
    getData,
    storeData
} from './StorageManager';
import {
    writeDebug,
    writeLog,
    writeSuccess
} from './LoggerService'
import {
    registerNotiHubDevice,
    updateNotiHubDevice
} from './ConfigDevice';
import NotificationHub from './NotificationHub';


class NofiticationManagerFCM {

    getAPNSToken = async () => {
        try{
            if(!messaging().isDeviceRegisteredForRemoteMessages)
                return;
            let tries = 0;
            while (tries < 4) {
            const apnsToken = await messaging().getAPNSToken();
            if (apnsToken !== null) return apnsToken;
            await new Promise((resolve) => setTimeout(resolve, 1000));
            tries++; 
            } 
        }catch(err){
            writeDebug('Error en permisos Noti APNS',err);         
        }
      }

    registerAppWithFCM = async (auth) => { 
        if (Platform.OS === 'ios' ){  
            try{
                let atl = await messaging().registerDeviceForRemoteMessages();
                writeSuccess('APNS Registrered con', auth? auth.toString() :'(Ya solicitado)'); 
                await messaging().setAutoInitEnabled(true);
                let tokenAPNS = await this.getAPNSToken()
                writeDebug('Token APNS', tokenAPNS);   
            }
            catch(err){
                writeDebug('Error APNS', err);
            }
            // } 
        }
    };

    registerFCM = async (
        onRegister,
        onNotification,
        onOpenNotification
    ) => { 
        await this.checkPermission(onRegister); 

        await storeData('sys_notiTokenIdAPNS', null);

        messaging().onTokenRefresh(async (fcmToken) => {
            await storeData('sys_notiTokenId', fcmToken);
            updateNotiHubDevice(fcmToken);
        });

        messaging().onNotificationOpenedApp(async (remoteMessage) => {
            writeDebug('Abierto Noti',remoteMessage);   
            await onOpenNotification(remoteMessage); 
        });

        messaging().setBackgroundMessageHandler(async (remoteMessage) => { 
            writeDebug('Llegada Noti Background',remoteMessage);  
            onNotification(remoteMessage);
        });

        messaging()
            .getInitialNotification()
            .then((remoteMessage) => {
                if (remoteMessage) {
                    NotificationHub.syncNotification(remoteMessage, 2);
                }
            });

        messaging().onMessage((remoteMessage) => {
            writeDebug('Llegada Noti OnMessage',remoteMessage);   
            if (remoteMessage) {
                onNotification(remoteMessage);
            }  
        });
    };

    refreshToken = async () => {
        await messaging().deleteToken();
        await this.requestUserPermission();
    };

    requestUserPermission = async (onRegister) => {
        let userPermission  = await messaging().requestPermission();
        writeDebug('Permiso cedido',userPermission);  
        if(userPermission == messaging.AuthorizationStatus.AUTHORIZED || userPermission == messaging.AuthorizationStatus.PROVISIONAL)
            await this.getFcmToken(onRegister);
        else 
            await storeData('sys_notiTokenId', null);
             
    };

    requestOnlyUserPermission = async (onRegister) => {
        return messaging().requestPermission();
    };

    getFcmToken = async (onRegister) => {
        let fcmToken = null;
        try{
            fcmToken = await messaging().getToken(); 
        }
        catch(err){ 
            writeDebug('Error al obtener token',err);  
        }
        if (fcmToken) {
            let token = await getData('sys_notiTokenId');
            await storeData('sys_notiTokenId', fcmToken);
            writeDebug('Token en Memoria',token);  
            writeDebug('Token obtenido',fcmToken);  
            if (!token) { 
                await registerNotiHubDevice(fcmToken);
            } else {
                await updateNotiHubDevice(fcmToken);
            } 
        } else {
            writeLog('Token FCM', 'No token received');
        }
    };

    getCurrentToken = async () => {
        let token = await messaging().getAPNSToken();
        return token;
    }

    checkPermission = async (onRegister) => {
        try{
            let enabled =  await messaging().hasPermission(); 
            writeDebug('Tiene Permiso Noti',enabled);   
            if (enabled == messaging.AuthorizationStatus.AUTHORIZED || enabled == messaging.AuthorizationStatus.PROVISIONAL) {
                await this.getFcmToken(onRegister);
            } else {
                await this.requestUserPermission(onRegister);
            }
        }catch(err){
            writeDebug('Error en permisos Noti',err);         
        }
    };
}

export default new NofiticationManagerFCM();

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:9

github_iconTop GitHub Comments

1reaction
treesencommented, Jan 30, 2021

@surafelbm @JavaDumb I did it work! But at time, I’m not having time to post my solution, perhaps you can send me a message here gavidia.alex@gmail.com or at Messenger Alexis Gavidia Meza, I’ll help you 😉

can you help me, I am running into this issue too.

0reactions
game8149commented, Apr 7, 2021

@game8149 so how did you solve the problem?

Yeah, use the RN Messaging & App latest version.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ios - Receive push when app is closed - Stack Overflow
I am trying to save a data that comes with push notification payload. It works well when the app is running ...
Read more >
iOS Receiving Push Notification's only after close/reopen app.
When I install and open app at first time, allow notification's permission and check that I've received APNS Token and Token Firebase, ...
Read more >
Will iOS awake my app when i receive silent push notification ...
Sadly I don't think what you're attempting is possible on iOS using notifications. They are either unreliable (silent push) or don't wake your...
Read more >
Handling incoming iOS notifications - Pusher Beams Docs
Apple does not offer a way to handle a notification that arrives when your app is closed (i.e. when the user has fully...
Read more >
Do push notifications work when an app is closed in iOS?
Push notifications are messages sent by mobile apps to notify users of important information without them having to open them. As the app...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found