Search code examples
iospush-notificationapple-push-notificationsfirebase-cloud-messagingsilentpush

Unable to receive silent notification when app is inactive iOS


I am developing an app and i am using silent push notification, to send some data. Push is working fine when app is active but if i swipe out the app or it's inactive, my app is not receiving the push notification. I have enabled push notification in background mode under capabilities and also added required background mode key in info.plist

This is the sample data what i am sending along with push

  {
   "aps": {
      "content-available": 1
    },
    "yourdatakey":{data}
}

What should i do to fix this issue??.. Can an iOS app receive silent push notification in inactive mode?

    -(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void(^)(UIBackgroundFetchResult))completionHandler
{    
    if( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO( @"10.0" ) )
    {
        NSLog( @"iOS version >= 10. Let NotificationCenter handle this one." );
        return;
    }
    NSLog( @"HANDLE PUSH, didReceiveRemoteNotification: %@", userInfo );

    if( [UIApplication sharedApplication].applicationState == UIApplicationStateInactive )
    {
        NSLog( @"INACTIVE" );
        completionHandler( UIBackgroundFetchResultNewData );
    }
    else if( [UIApplication sharedApplication].applicationState == UIApplicationStateBackground )
    {
        NSLog( @"BACKGROUND" );
        completionHandler( UIBackgroundFetchResultNewData );
    }  
    else  
    {  
        NSLog( @"FOREGROUND" );  
        completionHandler( UIBackgroundFetchResultNewData );  
    }  
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
    NSLog( @"Handle push from foreground" );
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)())completionHandler
{
    NSLog( @"Handle push from background or closed" );
}

Push has a crucial role in my app and don't want any kind of delay. What should i do to receive push immediately??...


Solution

  • As far as I've been able to tell, the silent push notification should look something like this for :

    { 
          "to" : "<DEVICE_ID>",
          "priority" : "high",
          "content_available" : true,
          "data" : { "custom_key":"custom value", "custom_key_2":"custom value 2" }
    }
    

    For me, this sends nearly immediately when the app is in the foreground or the background. However, when the app is inactive, it does not come through at all (it does not launch the app to process the message).

    If I add the following to the message:

      "notification" : { "body" : "Notification Text", "sound" : "chime.aiff" }
    

    It will play the chime sound and display "Notification Text" in the notification area when the app is inactive, but still will not launch the app to process the data portion of the message. I understand this is probably by design, but I was using this to confirm that I was getting -something- while the app was inactive.

    So, this might help you with half of your question (getting the push notification immediately), but I'm afraid I'm still trying to get it to work while the app is inactive.

    Edit: It appears if the user force-closes the app (swipe up from the task manager), Apple disables launching the app when a push notification comes in. There is nothing you can do about it. Apple's documentation states that if you manually launch the app again or restart the device, it will re-enable launching the app from silent push notificaions, but I have not found that to be the case. I think the short answer is: "silent push notifications on iOS work when Apple decides to let them work." I guess if you need a mobile operating system that works in an expected way, direct your users to Android.