0

This can be an old question, but still I want to know what could be the several reasons for no push notifications received by few users, not all.

I have implemented the Push in an application, which works on, Development Profile, Adhoc Profile and Distribution Profile. All settings and configurations are done very cautiously, and it works. But not for all even if Push are enabled and permissions are given.

I keep 3 devices with all 3 Profiles, I use TestFlight for Distribution Profile.

Now from api, we are using gateway.push.apple.com for Adhoc and TestFlight builds, and gateway.sandbox.push.apple.com for Development, we have tried changing these too. But still we are not able to make it work for all the users.

Is there anything specific we are missing?

Update

This is how our Payload looks like

aps = {
        alert = "New message from iphonic";
        badge = 1;
        eventid = 76;
        notifytype = message;
        senderuserid = 0;
        sound = default;
};

Thanks.

iphonic
  • 12,615
  • 7
  • 60
  • 107
  • you are mention that you have already created Development,Adhoc& Distibution profile but you should also provide that to your php developer and some few changes in your project like set Background mode for remote notification – Bhumesh Purohit Jun 06 '16 at 13:48
  • Check your .pem files. What type of pushnotification certificates used by you to create them. APNS development or APNS Distribution.. – BhushanVU Jun 06 '16 at 13:50
  • @BhumeshPurohit Why would PHP dev require Provisioning Profiles they need .pem file only, NO? Do you mean anything else? – iphonic Jun 06 '16 at 13:58
  • 1
    @BhushanVU PEM files are correct as there are devices which can receive notifications but not all. – iphonic Jun 06 '16 at 13:59
  • ok. we can try to track it by writing a test script, input only single device token of the device which is unable to receive push notification. Just send a simple text and make sure App is either in background or terminated before running that test script. – BhushanVU Jun 06 '16 at 14:04
  • @Bhurmesh Purohit. What would the php developer do with the profiles? I think you are perhaps confusing profiles with ssl certificates, the server needs the ssl certificates, it can do nothing with the profiles. – Gruntcakes Jun 06 '16 at 15:07
  • we need to provide pem file to php so using that we can get notifications. Also we need to pass device id for sending notification to that particular device. – Bhumesh Purohit Jun 07 '16 at 04:54
  • Sending push notifications requires an SSL connection to APNS, secured by the push certificate you just created. That’s where .pem comes in. Rename .pem to ck.pem and replace the existing ck.pem in the perticuler folder you have created. @iphonic if you required then i will provide you step by step process – Bhumesh Purohit Jun 07 '16 at 05:44

4 Answers4

2

While there are other reasons, in a very high percentage of the time the reason for a push failure is due to the fact that the push “equation” has been broken.

There are two equations, either one of which must be followed exactly in order for pushes to work.

The Development equation:

Development build of the App + Development APN token + Development Certificate + Development Apple gateway == SUCCESS

The Production equation:

Production build of the App + Production APN token + Production Certificate + Production Apple gateway == SUCCESS.

If you have any dev element in the production equation, or any production element in the development equation then the push will NOT work. All four elements of the equation must be either all development or all production.

When you run the app via Xcode it will be a development build of the app by default (it can be changed in the scheme but unless you know this and have done so then it will be a debug build) and thus when using Xcode you must use the development equation for pushes to function. If you create an ad-hoc distribution or app store build then it will be a production build and you must use the production equation for it to work.

If creating an ad-how / distribution / app store build etc. then a common cause of failure is not setting Xcode's code-signing and provisioning profiles section in the build setting appropriately.

Also the production build of the app and the development build of the app result in different push tokens, so if you are temporarily hard-coding a token into some server test script or similar, then you must make sure its the correct token. In older versions of iOS the tokens would effectively never change once you had obtained it (they could, but the circumstances when it would were rare). But in iOS9 this is no longer the case and the token can and does change, so always make sure the token you are using on the server is up to date.

Pushes must also be sent over the correct gateway, the Apple development gateway is the sandbox gateway:

ssl://gateway.sandbox.push.apple.com:2195

While the production gateway is:

ssl://gateway.push.apple.com:2195

When using the production gateway the server must be signed with the production certificate of course, and signed with the development certificate when using the sandbox gateway.

If you use the same password for both certificates then you can sign your server with both the production certificate and development certificate in the same .pem file. I.e. You can concatenate all the elevate certificates and keys into a single .pem file and use that to sign the server. The server will of course need to use the sandbox gateway when testing using Xcode and the production gateway for the final app store release.

Gruntcakes
  • 37,738
  • 44
  • 184
  • 378
  • Thanks for the information, we are following all the majors you defined here, separating Development and Production environments, updating Tokens etc, and .pem files are correct too, if we fail to satisfy all no device would receive Push, where 80% of devices does. – iphonic Jun 06 '16 at 14:56
  • If you are 100% sure that the builds on all 3 devices are the same (and of course pushes are enabled on the devices) and the pushes get delivered to some but not the others, then the only variable is the push token. How are you getting the push token from the device to the server? Also is it a foreground or background push? (ie. a push directed to the user or a push directed to the app?) – Gruntcakes Jun 06 '16 at 15:01
  • I am 200% sure. We have api which updates push_tokes to server db on each launch, its background push when app is not running. – iphonic Jun 06 '16 at 15:04
  • "when app is not running" Background pushed don't get delivered to the app if its not running. By "not running" do you mean the app has been terminated or its – Gruntcakes Jun 06 '16 at 15:09
  • Push will show notification when app is in background, or not running. It doesn't even work if in Foreground for obvious reasons. – iphonic Jun 06 '16 at 15:12
  • @iphonic Not a background app-directed push. A user-directed push has the behavior you described. An app-directed push is not visible to the user nor is it delivered to the app if the app is terminated. The op has said they are using a background push. – Gruntcakes Jun 06 '16 at 15:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/113938/discussion-between-iphonic-and-the-pumping-lama). – iphonic Jun 06 '16 at 15:14
0

There are following reasons of not getting push notifications on device :

  1. Passphrase of certificate and added in server side code are different.
  2. Size of push notification payload is exceeding. It should be below 2048 KB as per apple standard. It is called as payload. If you payload (notification object) size is greater than 2048 KB, then APNS will not process it so does device will not get it.
  3. Wrong device token sent from iPhone application to server. Refer Get device token
  4. Finally, if server is sending push notification for both iOS and Android, then make sure that you are sending notification to correct device as iOS will get it from APNS and android will get it from GCM. In this case while registration you can get device type from user and save it in your database. So it can be used while sending notifications.

These are the possible scenarios in my view. Let me know if it works for you or now.

Community
  • 1
  • 1
Pushkraj Lanjekar
  • 2,254
  • 1
  • 21
  • 34
  • Thanks for answer. 1. NO all informations are correct as it works but not for all. 2. We sent just "Hi" as payload. 3. Is there any way to know if device token is wrong? 4. Both Android and iOS handled separately so this is not an issue, on top of that Android is able to receive fine. – iphonic Jun 06 '16 at 14:02
  • If its working good in android then there could be 2 scenarios 1. Size of payload is exceeding 2. Wrong device token. Working code of getting device token is mentioned in answer. And we cant validate device token. – Pushkraj Lanjekar Jun 07 '16 at 05:27
  • I have updated the Payload in my question don't think that is exceeding, what is other scenario? – iphonic Jun 07 '16 at 05:29
0

use this to send test notif. and don't forget to add also the .pem to server, not onlt the .php file

<?php

// Put your device token here (without spaces):
$deviceToken = '';

// Put your private key's passphrase here:
$passphrase = '';

// Put your alert message here:
$message = 'Salut!';

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'yourFile.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);


// Open a connection to the APNS server
$fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
    exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
    'alert' => $message,
    'sound' => 'default'
    );

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

if (!$result)
    echo 'Message not delivered' . PHP_EOL;
else
    echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);
0

There are a couple problems that might arise:

  1. Some notifications received but not all: If you’re sending multiple push notifications simultaneously and only a few are received, fear not! That is intended behaviour. APNS maintains a QoS (Quality of Service) queue for each device with a push app. The size of this queue is 1, so if you send multiple notifications, the last notification is overridden.
  2. Problem connecting to Push Notification Service: One possibility could be that there is a firewall blocking the ports used by APNS. Make sure you unblock these ports. Another possibility might be that the private key and CSR file are wrong. Remember that each App ID has a unique CSR and private key combination.
Bhumesh Purohit
  • 491
  • 1
  • 8
  • 26