Push Notifications for multiple Apps from one server
Asked Answered
P

1

23

I am using RMSPushNotificationsBundle for handling push notifications. I am sending pushNotifications to multiple apps from one server. I am using setAPNSPemAsString method which pick right certificate. But push notification is sent only first time. Can anyone tell me why? Thank you!

public function sendIOS($appName){
    $notifications = $this->container->get('rms_push_notifications');

    $message = new iOSMessage();
    $message->setMessage($this->message);
    $message->setData($this->getData());
    $message->setAPSSound("default");
    $message->setDeviceIdentifier($this->pushToken);

    if ($appName !="appName") {
        $pemFile    = $this->container->getParameter("rms_push_notifications.ios.".$appName.".pem");
        $passphrase = $this->container->getParameter("rms_push_notifications.ios.".$appName.".passphrase");

            $pemContent = file_get_contents($pemFile);
            $notifications->setAPNSPemAsString($pemContent, $passphrase);
    }
    return $notifications->send($message);
}
Pyrogallol answered 1/10, 2015 at 13:25 Comment(5)
Do you have anything in the logs? Also, where is $appName being set?Baese
with appName is just one variable which we use to decide which certificate we use for push notifications. With appName we know which version of our application user uses on his phone. Using setAPNSPemAsString function works only once with first push notification on others send function returns us false..Pyrogallol
For IOS the bundle includes a Feedback service. Maybe you can find an answer here. Did you see it? github.com/richsage/…Hair
1. Are you sure $appName is correct every time 2. What do you mean with only first time ... is it called more then once in one script run or in a loop. 3. how many notifications are you trying to send, 1-10, 100-1000?Caudill
Are you saying it works for 1 push to 1 device and then it dies?Jackstraws
E
1

I'm not sure what's the problem but following small code worked for me. At least you can use this to test connection to APNS server.

<?php
// your private key's passphrase
$passphrase = $_POST('passphrase');

$pemFilesPath = 'path/to/pem/folder/';

// path to pem file
$appCert = $_POST('pemfile');

$pemFile = $pemFilePath.$appCert;

$notifications = $_POST('notifications');

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

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $pemFile);
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;

$records = 0;

foreach ($notifications as $deviceToken => $message)
{
    // 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;

    if (!$fp) {
        exit("Connection intruptted " . E_USER_ERROR . PHP_EOL);
    }
    // Send it to the server
    $result = fwrite($fp, $msg, strlen($msg));
    if(!$result) {

                                print_r("Failed writing to stream.", E_USER_ERROR);
                                fclose($fp);
                                die;
                        }
                     /* uncomment this part for troubleshooting   
                        else {
                                $tv_sec = 1;
                                $tv_usec = null; // Timeout. 1 million micro seconds = 1 second
                                $read = array($fp); $we = null; // Temporaries. "Only variables can be passed as reference."
                                $numChanged = stream_select($read, $we, $we, $tv_sec, $tv_usec);
                                if(false===$numChanged) {
                                        print_r("Failed selecting stream to read.", E_USER_ERROR);
                                        fclose($fp);
                                        die;
                                }
                                else if($numChanged>0) {
                                        $command = ord(fread($fp, 1));
                                        $status = ord(fread($fp, 1));
                                        $identifier = implode('', unpack("N", fread($fp, 4)));
                                        $statusDesc = array(
                                                0 => 'No errors encountered',
                                                1 => 'Processing error',
                                                2 => 'Missing device token',
                                                3 => 'Missing topic',
                                                4 => 'Missing payload',
                                                5 => 'Invalid token size',
                                                6 => 'Invalid topic size',
                                                7 => 'Invalid payload size',
                                                8 => 'Invalid token',
                                                255 => 'None (unknown)',
                                        );
                                        print_r("APNS responded with command($command) status($status) pid($identifier).", E_USER_NOTICE);

                                        if($status>0) {
                                                $desc = isset($statusDesc[$status])?$statusDesc[$status]: 'Unknown';
                                                print_r("APNS responded with error for pid($identifier). status($status: $desc)", E_USER_ERROR);
                                                // The socket has also been closed. Cause reopening in the loop outside.
                                                fclose($fp);
                                                die;
                                        }
                                        else {
                                                // Apple docs state that it doesn't return anything on success though
                                               $records++;
                                        }
                                } else {
                                        $records++;
                                }
                        }
                        */  
    $records++;
    }

echo "Send notifications to $records devices";
// Close the connection to the server
fclose($fp);

?>

Note: Wrote this small code long time ago and it worked fine. I don't remember the source now but there was a tutorial. Have not tested recently so you may need to revise it. Some suggestions:

  1. Open connection and write to the server all your notifications then close it.
  2. Reading server response reduces functionality but is good for troubleshooting and for start. So use that part as needed.
  3. Take a look at this documentation for more error explanation APNs Provider API
Eskimo answered 19/3, 2016 at 5:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.