5
votes

With my app on the App Store, push notifications are not working. With my app in Development, push notifications are working.

I guess I should have tested via an Ad Hoc deployment. Anyway, here is what I know...

App ID

my App ID is com.MyName.My-App

It has Push Notifications enabled for Development and Distribution

enter image description here

APNs Certificates

I have both Development and Distribution certificates. It's the Dist I care about.

enter image description here

It has the name com.MyName.My-App

Exporting to a PEM

I've selected both the Cert and private key, and exported it, as follows:

enter image description here

and password protected it.

I then ran

openssl pkcs12 -in Certificates.p12 -out pushcert.pem -nodes -clcerts

supplying the password, and successfully getting the pushcert.pem output.

Downloading App

I cleared by server side device token for my device, I download my app from the app store, opened it and accepted Push Notifications, and then logged into my server to check my device token. I have my production device token now. I ran this simple php script (which works when I supply my development device token) but fails with my production device token.

<?php

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

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

// Put your alert message here:
$message = 'Test';

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

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'pushcert.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');

// Open a connection to the APNS server
$fp = stream_socket_client(
    'ssl://gateway.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);

Why is it failing? It works with my development device token, but not my production device token. Have I not done something correctly?

3
you try build adhoc with current certificates for push notification? Maybe your add on store use difference certificate.vien vu

3 Answers

4
votes

What is happening is that you likely are distributing with the wrong provisioning profile. In order to receive Push Notifications in the final release, you need to have the newest provisioning profile installed in which you have already enabled Push Notifications for distribution. This is the most common mistake and I encountered it once or twice in the past.

So now you have to take the following steps:

  • Log in to the Apple Developer Center
  • Create a new Provisioning Profile for this App id for distribution Screenshot
  • Continue to set it up fully, by entering all the necessary details
  • Download the profile and double-click it to install it
  • In your project under Build Settings-> Code Signing -> Distribution select your newly created profile
  • Now Push Notifications will reach the end user also in the Distribution builds.

Hope that helps, Julian.

0
votes

Make sure you are not using the sandbox cert on the server! you have to change this in order for it to work from sandbox to prod.

0
votes

It turns out it was a problem with the third party Ruby Gem I was using (rpush). Not exactly sure what, but as soon as I switched it out, everything has been great.