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.

I am not receiving data messages to IOS device on background and killed state.

See original GitHub issue

Hi, I am not receiving data messages in some cases to the IOS device. My server sends data messages with content_available:“true”. My expected results when an notification arrived are :

  1. Save the data
  2. Present a tray notification if the app is in one of the 3 states: killed, background, foreground but not in the right screen.

My actual results are:

  1. When the app is killed the notification never arrives or presented.
  2. When the app is in background : the first 9 notifications arrives and presented as expected, then the next notifications are not presented , but when i open the last one that was sent id presented. If I wait about 30 minutes in background state , I can receive again just 9 notifications.
  3. When the app is in foreground the notifications arrives and presented as expected
  4. Sometimes I get twice or even 4 times the same notification.

Here is my code:

import FCM, { FCMEvent,
              NotificationType,
              WillPresentNotificationResult,
              RemoteNotificationResult } from 'react-native-fcm';
import { Platform,AppState} from 'react-native';
import deviceLog from 'react-native-device-log'
import AnalyticsUtil from '@helpers/AnalyticsHelper';
import {
  PUSH_TYPE_CHAT_MESSAGE,
  PUSH_TYPE_CHAT_INVITATION,
  PUSH_TYPE_CHAT_INVITATION_APPROVED
} from '@helpers/Constants';

import NavigationService from './NavigationService';

import Server from './Server'
import Storage from './RealmStorage';
import Users from './Users';




const FCM_ENABLED=true;


class FCMHelper {


  async setBadge(badge)
  {
    await FCM.setBadgeNumber(badge)
  }

  async resetBadge()
  {
     await FCM.setBadgeNumber(0);
  }

  async claculateBadge(count)
  {
     await FCM.setBadgeNumber(badge);
  }




  async getToken()
  {
    if(!this.enabled)
    {
      console.warn('FCM disabled')
      return null;
    }
    let token = await FCM.getFCMToken();
    return token;
  }

  registerToToken(callback)
  {
    if(!this.enabled)
    {
      console.warn('FCM disabled')
      return null;
    }
    FCM.on(FCMEvent.RefreshToken, token => {
      callback(token);
    });
  }

  registerToNotification(isChatOpen,loadMessages,loadChats,loadChatRequests,isChatRequestsOpen)
  {
      this.isChatOpen =isChatOpen;
      this.loadMessages=loadMessages;
      this.loadChats=loadChats;
      this.loadChatRequests=loadChatRequests;
      this.isChatRequestsOpen=isChatRequestsOpen;
  }

  async initFCM() {
     deviceLog.log("init fcm");
    try
    {
        let result = await FCM.requestPermissions({badge: true, sound: true, alert: true});
        console.log("FCM.requestPermissions result",result)
        FCM.enableDirectChannel();
        let token = await FCM.getFCMToken();
        FCM.getInitialNotification().then(notif => {
          console.log("INITIAL NOTIFICATION", notif);
        });

        FCM.on(FCMEvent.Notification, this.handleNotification);

        FCM.on(FCMEvent.RefreshToken, token => {
            console.log("fcm refresh token",token)
            this.refreshToken(token);
        });

        FCM.on(FCMEvent.DirectChannelConnectionChanged, (data) => {
          console.log('direct channel connected:' , data);
        });

        setTimeout(function() {
          FCM.isDirectChannelEstablished().then(d => console.log('isDirectChannelEstablished:',d));
        }, 1000);
        this.enabled=true;
        console.info('FCM succed','token:',token)
        return token;
    } catch(e)
    {
      console.warn('FCM failed',e)
      this.enabled=false;
      return null;
    }
  }


  handleNotification= async (notif)=>
  {
    deviceLog.log('notification: t:'+notif.type +' nt:'+notif._notificationType,'Appstate:'+AppState.currentState,notif)
    console.log('new notification. Appstate: ',AppState.currentState,' notification: ',notif)
    switch (notif._notificationType) {
        case NotificationType.Remote:
            /*const PUSH_TYPE_CHAT_MESSAGE = "chat_message";
            const PUSH_TYPE_CHAT_INVITATION = "invitation";
            const PUSH_TYPE_CHAT_INVITATION_APPROVED = "chat_invitation_approved";*/
            let event=invitation=inviting=titleText=subtitleText=null;

            switch (notif.type)
            {

              case PUSH_TYPE_CHAT_MESSAGE:
                //save message
                let message= JSON.parse(notif.message);
                let {author,chat,text}= message;
                let chatOpen =this.isChatOpen(chat)
                await Storage.insertChatMessage(chat,author,text,!chatOpen);
                // findout navigation screen compare to 'ChatDetails' and props.chatId == chatid
                await this.loadChats(true);
                if (!chatOpen){
                  FCM.presentLocalNotification({
                        title: "New Message:"  + notif.author_name,
                        body: notif.text,
                        show_in_foreground: true,
                        data:{
                          chat,
                          type: PUSH_TYPE_CHAT_MESSAGE,
                          author
                        },
                        sound: "default",
                        //badge:
                  })
                }
                else{
                    await this.loadMessages(chat,true);
                }
                notif.finish(RemoteNotificationResult.NewData);
                break;

              case PUSH_TYPE_CHAT_INVITATION:
                let chatRequestsOpen =this.isChatRequestsOpen()
                invitation= JSON.parse(notif.invitation);
                event = invitation.event;
                inviting= invitation.inviting;
                titleText = "New chat invitation";
                subtitleText = "from " + inviting.name;
                if (event && event != "null") {
                  subtitleText+= "\nabout " + event;
                }
                await this.loadChatRequests();
                if (!chatRequestsOpen){
                  FCM.presentLocalNotification({
                        title: titleText,
                        body: subtitleText,
                        show_in_foreground: true,
                        data:{
                          chat:invitation.id,
                          author:inviting.id,
                          type: PUSH_TYPE_CHAT_INVITATION
                        },
                        sound: "default",
                        //badge:
                  })
                }
                notif.finish(RemoteNotificationResult.NewData);
                break;

              case PUSH_TYPE_CHAT_INVITATION_APPROVED:
                invitation= JSON.parse(notif.invitation);
                event = invitation.event;
                let chatId= parseInt(notif.chatId)
                let approvedBy= parseInt(notif.approving_by);
                titleText = "New available chat with";

                let user = await Users.fetchUsers([approvedBy],true);
                user =user[0];
                let name = user.name;
                subtitleText = name?name+" ":"";
                subtitleText= subtitleText+ "wants to talk to you";
                if (event && event != "null") {
                  subtitleText+= " about " + event;
                }
                await Storage.insertChatMessage(chatId,approvedBy,subtitleText,true,true);
                // findout navigation screen compare to 'ChatDetails' and props.chatId == chatid
                await this.loadChats(true);
                FCM.presentLocalNotification({
                      title: titleText,
                      body: subtitleText,
                      show_in_foreground: true,
                      data:{
                        chat:chatId,
                        author:approvedBy,
                        type: PUSH_TYPE_CHAT_INVITATION_APPROVED
                      },
                      sound: "default",
                      //badge:
                })
                break;

              default:
                break;
            }
            break;
        case NotificationType.WillPresent:
            //do nothing
            notif.finish(WillPresentNotificationResult.ALL); //other types available: WillPresentNotificationResult.None
            break;
        case NotificationType.NotificationResponse:
          switch (notif.data.type)
          {
            case PUSH_TYPE_CHAT_MESSAGE:
            case PUSH_TYPE_CHAT_INVITATION_APPROVED:
              //navigate to chat
              let {author,chat} =notif.data;
              let user = await Users.fetchUsers([author],true);
              user =user[0];
              let thumbUrl = Users.getThumbUrl(user)
              let name = user.name
              let notifType = notif.data.type==="chat_message"?"Chat Message":"Chat Request Approved";
              AnalyticsUtil.recordEvent("Notification - "+notifType);
              NavigationService.navigate('ChatDetails', { name,thumbUrl,chatId:chat });
              notif.finish();
              break;
            case PUSH_TYPE_CHAT_INVITATION:
              AnalyticsUtil.recordEvent("Notification - Chat Request");
              NavigationService.navigate('ChatRequests');
              notif.finish();
              break;
            default:
            notif.finish();
              break;
        }
        default:
          notif.finish();
          break;
      }
  }

  async refreshToken(token)
  {
     deviceLog.log("refresh fcm token");
    if(!this.enabled)
    {
      console.warn('FCM disabled')
      return;
    }
    token = token||await this.getToken();
    Server.updateFCMToken(token);
  }
}

const fCMHelper = new FCMHelper();
export default fCMHelper;

And here is an example of the notification received from the server:

{
	"to": ".....",
	 "content_available":true,
	 "priority":"high",
	  "show_in_foreground": true,
	
	"data": {
                "alert": "Chat Message",
                "id": 12234,
                "title": "title",
                "subtitle": "subtitle",
                "chat_id":222,
                "author_id": 333,
                "author_name": "Elad Cohen",
                "text": "text",
                "type": "chat_message",
                "message": {"author":111,"chat":22,"created":null,"id":null,"text":"text"}
	}
}

Thanks Elad

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
evollucommented, Aug 17, 2018

for iOS, when notification arrives with content_available:true, it will wake JS and callbacks will be executed if they are not registered in a component. however, if user force kill the app, there is no way to run logic until app is opened by user again. system limit

0reactions
temitopecommented, Oct 29, 2018

@evollu thank you for an incredible library. Ive benefited so much. Of note, using firebase to send push notifications I had to leave out content_available entirely to avoid errors. upon removal everything was working great. I needed it to allow people to reply to messages from the notification tray (iOS). I run a database save (it is a promise). This works even if the app is killed in my experience. Again, many thanks. If needed i hope to contribute my thanks with code as well. such a good library.

Read more comments on GitHub >

github_iconTop Results From Across the Web

App does not launch by data FCM | Apple Developer Forums
Hi all,. We used to launch our app in background by a silent FCM push and the app will display a local notification...
Read more >
FCM Swift - Application does not receive message data in ...
It would seem that my application does not receive a message (notification or data) in background. The application can receive messages ( ...
Read more >
iOS Push Notifications not received when app is terminated ...
From the answers of this post IOS data notifications with FCM, Data messages can't be received in iOS if the app is killed....
Read more >
Notifications Not Shown - Mobile Push
When an app is in a Force Stopped / Force Killed state most events including FCM messages for push notifications will not be...
Read more >
iOS Troubleshooting - Airship Docs
Apple reserves the right to not wake up your application when a background notification is received in order to maximize the devices battery...
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