ios 和 android 向多个设备推送通知 [英] ios and android push notifications to multiple devices

查看:68
本文介绍了ios 和 android 向多个设备推送通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很挣扎.这段代码不是我创建的,但我已经对其进行了更改,因此它可以正常工作.我的目标是让它能够向所有使用该应用程序的设备发送推送通知.我是一个ios和andriod编程的所以我会尽力而为.我已经清理并更改了给我的代码,以便它现在只向一台设备发送通知.

I am really struggling with this. This piece of code wasn't created by me but I have changed it so it sort of works. My goal is for it to be able to send push notifications to all devices that use the app. I am an ios and andriod programmed so I will try my best. I have cleaned up and changed the code that was given to me so that it will now send a notification to just one device.

这是代码

<?php 
include 'conn.php'; 


if ( $_REQUEST['key'] == 'notification' ) {

    include 'notifications.php';
    $message = $_REQUEST['text'];
    $text = mysql_real_escape_string( $_REQUEST['text'] );
    $start = $_REQUEST['start'];
    $end = $_REQUEST['end'];
    $date = date( "Ymd", strtotime( $_REQUEST['date'] ) );
    $callus = $_REQUEST['callus'];
    $in = "INSERT INTO `notifications` (`date`, `start_time`, `end_time`, `text`, `call_us`) VALUES ('$date', '$start', '$end', '$text', '$callus');";
    mysql_query($in);

} else {

    $message = mysql_real_escape_string( $_REQUEST['text'] );
    $time = date( 'Y-m-d H:i:s' );
    $in = "INSERT INTO `alerts` (`text`, `time`) VALUES ('$message', '$time');";
    mysql_query( $in );
    $sel="SELECT * FROM `users` GROUP by device_token";
    $rs = mysql_query( $sel ) or die('');

        if ( mysql_num_rows( $rs ) != 0 ) {
             while( $row=mysql_fetch_array( $rs ) ) {   
                $regi = array();        
                $regi[] = $row['device_token'];
                $dev = $row['device_token'];

                    if( strlen ( $dev ) > 65 ) {
                        $regis[] = $row['device_token'];
                    } else {
                        $ios[] = $dev;
                    }
                }
            }


$url = 'https://android.googleapis.com/gcm/send';
      $fields = array( 'registration_ids' => $regis, 'data' => array( 'message'=>$message,'count'=>1 ) );
$headers = array(
            'Authorization: key=AIzaSyCMysH7TySEgdbvRoCLoZk8uFF1x_A3uxg',
            'Content-Type: application/json'
        );

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode ( $fields ) );
$result = curl_exec( $ch );
curl_close ( $ch );

//Apple Push notification

    // This this a fake device id:
$deviceToken = "5d8b3165fc03645d23c2651badd69f07d028aee801acf1d25a4d230882156755";

// fake password:
$passphrase = '123456789';

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

// 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);

}
include 'index.php';

?>

我将 ios 设备令牌添加到 $deviceToken 并将 android 设备令牌添加到 $regi,它将发送到手机.我更改的唯一部分是 Apple 推送通知部分不起作用.在我更改它之前,苹果推送通知使用的是 $dev 变量,而 android 使用的是 $regi.现在我知道设备令牌在应用程序启动时被发送到服务器,所以我的猜测是它们没有存储在变量中.是否有任何问题您可以看到,我如何将它们打印出来以查看它们是否为空?

I add the ios device token to the $deviceToken and the android device token to the $regi and it will send to the phones. The only part I have changed is the Apple push notification part which didn't work. Before I changed it the apple push notification was using the $dev variable and android was using $regi. Now I know that the device tokens are being sent to the server when the app is launched so my guess is that they are not being stored in the variables. Is there any problems you can see and how can I print them out to see if they are empty?

谢谢

推荐答案

我不久前就想到了这一点,尽管我会分享给其他遇到困难的人.

I figured this out a while ago and though I would share for anyone else that is struggling.

<?php 
    include 'conn.php'; 

    if ( $_REQUEST['key'] == 'notification' ) {

        $message = $_REQUEST['text'];
        $text = mysql_real_escape_string( $_REQUEST['text'] );
        $start = $_REQUEST['start'];
        $end = $_REQUEST['end'];
        $date = date( "Ymd", strtotime( $_REQUEST['date'] ) );
        $callus = $_REQUEST['callus'];
        $in = "INSERT INTO `notifications` (`date`, `start_time`, `end_time`, `text`, `call_us`) VALUES ('$date', '$start', '$end', '$text', '$callus');";
        mysql_query($in);
        include 'notifications.php';

    } 
    else {

        $message = mysql_real_escape_string( $_REQUEST['text'] );
        $time = date( 'Y-m-d H:i:s' );
        $in = "INSERT INTO `alerts` (`text`, `time`) VALUES ('$message', '$time');";
        mysql_query( $in );
        $sel="SELECT * FROM `users` GROUP by device_token";
        $rs = mysql_query( $sel ) or die('');

        if ( mysql_num_rows( $rs ) != 0 ) {
            while( $row=mysql_fetch_array( $rs ) ) {    
                $regi = array();        
                $regi[] = $row['device_token'];
                $dev = $row['device_token'];

                if( strlen ( $dev ) > 65 ) {
                    $regis[] = $row['device_token'];
                } 
                else if ( strlen ($dev) > 25 ) {
                    $ios[] = $dev;
                }
            }   
        }

        $deviceToken=$_REQUEST['device'];
        $json=json_decode($deviceToken);

        //google Push notification

        // API access key from Google API's Console
        define( 'API_ACCESS_KEY', 'AIzaSyCMysH7TySEgdbvRoCLoZk8uFF1x_A3uxg' );

        //build the message
        $fields = array
        (
            'registration_ids'  => $regis,
            'data'              => array( 'message'=> $message,'count'=>1 )
        );

        $headers = array
        (
            'Authorization: key=' . API_ACCESS_KEY,
            'Content-Type: application/json'
        );

        $ch = curl_init();
        curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' );
        curl_setopt( $ch,CURLOPT_POST, true );
        curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
        curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
        $result = curl_exec($ch );
        curl_close( $ch );

        //Apple Push notification

        // Certificate password:
        $passphrase = '123456789';

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

        // 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);

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

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

        // Loop though device tokens
        foreach($ios as $dev) {
            if($dev!=''){
                // Build the binary notification
                $msg = chr(0) . pack('n', 32) . pack('H*', $dev) . pack('n', strlen($payload)) . $payload;
                //Send it to the server
                $result = fwrite($fp, $msg, strlen($msg));
            }
        }

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

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

        include 'index.php';
    }

?>

问题似乎是应用程序向数据库发送了一个开发设备令牌,所以我将 xcode 中的 didRegisterForRemoteNotificationsWithDeviceToken 函数更新为:

The problem seemed to be that the app was sending the database a development device token so I updated my didRegisterForRemoteNotificationsWithDeviceToken function in xcode to this:

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{
#ifdef DEBUG
    // Update the database with our development device token
    NSLog(@"IN DEVELOPMENT MODE!!!!!!!");
#else
    // Update the database with our production device token
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"content---%@", token);
    kSetValueForKey(@"device_token", token);
    [self updateDeviceToken:token];

#endif
}

我还发现,如果用户拒绝允许推送通知的请求,它会将设备令牌 0 发送到我的数据库,如果使用它会停止发送通知.所以我在我的 php 文件中对我的设备令牌进行排序时,我添加了更多的逻辑来忽略所有只有 0 的令牌.

Also I found that if a user denies the request to allow push notifications that it send a device token of 0 to my database, which if used stops the notifications from being sent. So where I'm sorting my device tokens in my php file I added more logic to ignore all the tokens that where just 0.

在将其添加到 $ios 数组之前,我只是检查了长度是否超过 25 个字符,而之前我没有

I simply just checked that the length was more than 25 characters before I added it to my $ios array, where as before I wasn't

旧代码:

if( strlen ( $dev ) > 65 ) {
  $regis[] = $row['device_token'];
} else {
  $ios[] = $dev;
}

新代码:

if( strlen ( $dev ) > 65 ) {
  $regis[] = $row['device_token'];
} else if ( strlen ($dev) > 25 ) {
  $ios[] = $dev;
}

我发现的主要问题之一是,如果您将设备令牌发送到苹果生产推送通知服务器,而该服务器不是有效的生产设备令牌,它只是不会向任何设备发送通知.这就是为什么我没有工作,我在我的 php 代码和 Objective-c 代码中添加了额外的逻辑来过滤掉所有无效的设备令牌.

One of the main problems I found is if you send a device token to apples production push notification server that isn't a valid production device token, it just doesn't send the notification to any device. This is why I It wasn't working and I have added in the extra logic to my php code and Objective-c code to filter out all the invalid device tokens.

希望这对人们有所帮助.

Hope this helps people.

这篇关于ios 和 android 向多个设备推送通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆