push notification - Echo Device Token Using Php -
how can echo $token
value in api.php
file? app uses push notifications , thusly $token
variable in api file gets set 64 character device token
each user gets when app downloaded. far token gets posted database, need able echo out. ultimate goal set $token global variable , pass new file use in additional php statements. echo can make sure can explicitly first.
<?php // server api pushchat iphone app. use api, app // sends http post request our url. post data contains field "cmd" // indicates api command should executed. try { // running in development or production mode? can switch // between these 2 in apache virtualhost configuration. if (!defined('application_env')) define('application_env', getenv('application_env') ? getenv('application_env') : 'production'); // development // in development mode, show errors because want // know them. don't in production mode because might // expose critical details of our app or our database. critical php errors // still logged in php , apache error logs, it's // idea keep eye on them. if (application_env == 'development') { error_reporting(e_all|e_strict); ini_set('display_errors', 'on'); } else { error_reporting(0); ini_set('display_errors', 'off'); } // load config file. prefer keep configuration settings in // separate file don't have mess around in main code if // want change settings. require_once 'api_config.php'; $config = $config[application_env]; // in development mode, fake delay makes testing more realistic. // you're running on fast local server in production // mode people using on mobile device on slow connection. if (application_env == 'development') sleep(0); //here // keep code clean, put api own class. create // instance of class , let handle request. $api = new api($config); $api->handlecommand(); echo "ok" . php_eol; } catch (exception $e) { // code throws exception when goes horribly wrong; e.g. // no connection database made. in development mode, // show these exception messages. in production mode, return // "500 server error" message. if (application_env == 'development') var_dump($e); else exitwithhttperror(500); } //////////////////////////////////////////////////////////////////////////////// function exitwithhttperror($error_code, $message = '') { //here switch ($error_code) { case 400: header("http/1.0 400 bad request"); break; case 403: header("http/1.0 403 forbidden"); break; case 404: header("http/1.0 404 not found"); break; case 500: header("http/1.0 500 server error"); break; } //here header('content-type: text/plain'); if ($message != '') header('x-error-description: ' . $message); //here /*exit;*/ } function isvalidutf8string($string, $maxlength, $allownewlines = false) { if (empty($string) || strlen($string) > $maxlength) return false; if (mb_check_encoding($string, 'utf-8') === false) return false; // don't allow control characters, except possibly newlines ($t = 0; $t < strlen($string); $t++) { $ord = ord($string{$t}); if ($allownewlines && ($ord == 10 || $ord == 13)) continue; if ($ord < 32) return false; } return true; } function truncateutf8($string, $maxlength) { $origstring = $string; $origlength = $maxlength; while (strlen($string) > $origlength) { $string = mb_substr($origstring, 0, $maxlength, 'utf-8'); $maxlength--; } return $string; } //////////////////////////////////////////////////////////////////////////////// //here new: try echo here class api { // because payload allows 256 bytes , there overhead // limit message text 190 characters. const max_message_length = 190; private $pdo; function __construct($config) { // create connection database. $this->pdo = new pdo( 'mysql:host=' . $config['db']['host'] . ';dbname=' . $config['db']['dbname'], $config['db']['username'], $config['db']['password'], array()); // if there error executing database queries, want pdo // throw exception. our exception handler exit script // "500 server error" message. $this->pdo->setattribute(pdo::attr_errmode, pdo::errmode_exception); // want database handle strings utf-8. $this->pdo->query('set names utf8'); } function handlecommand() { // figure out command client sent , let corresponding // method handle it. if command unknown, exit error // message. if (isset($_post['cmd'])) { switch (trim($_post['cmd'])) { case 'join': $this->handlejoin(); return; case 'leave': $this->handleleave(); return; case 'update': $this->handleupdate(); return; case 'message': $this->handlemessage(); return; } } exitwithhttperror(400, 'unknown command'); } // "join" api command registers user receive notifications // sent in specific "chat room". each chat room identified // secret code. users register same secret code can // see each other's messages. // // command takes following post parameters: // // - user_id: unique identifier. must string of 40 hexadecimal characters. // - token: device's device token. must string of 64 hexadecimal // characters, or "0" if no token available yet. // - name: nickname of user. must utf-8 string of maximum 255 // bytes. first 20 bytes shown in push // notifications. // - code: secret code identifies chat room. must utf-8 // string of maximum 255 bytes. // function handlejoin() { //function getuserid; global $userid; $userid = $this->getuserid(); $token = $this->getdevicetoken(true); $name = $this->getstring('name', 255); $code = $this->getstring('code', 255); // when client sends "join" command, add new record // active_users table. identify client user_id // provides. when client sends "leave" command, delete // record active_users table. // theoretically possible client sends "join" command // while user_id still present in active_users (because did not // send "leave" command). in case, remove old // record first , insert new one. $this->pdo->begintransaction(); $stmt = $this->pdo->prepare('delete active_users user_id = ?'); $stmt->execute(array($userid)); $stmt = $this->pdo->prepare('insert active_users (user_id, device_token, nickname, secret_code, ip_address) values (?, ?, ?, ?, ?)'); $stmt->execute(array($userid, $token, $name, $code, $_server['remote_addr'])); $this->pdo->commit(); } // "leave" api command removes user chat room. user // no longer receive push notifications messages sent room. // // command takes following post parameters: // // - user_id: unique identifier. must string of 40 hexadecimal characters. // function handleleave() { $userid = $this->getuserid(); $stmt = $this->pdo->prepare('delete active_users user_id = ?'); $stmt->execute(array($userid)); } // "update" api command gives user new device token. // // command takes following post parameters: // // - user_id: unique identifier. must string of 40 hexadecimal characters. // - token: device's device token. must string of 64 hexadecimal // characters. // function handleupdate() { $userid = $this->getuserid(); $token = $this->getdevicetoken(false); $stmt = $this->pdo->prepare('update active_users set device_token = ? user_id = ?'); $stmt->execute(array($token, $userid)); } // "message" api command sends message users registered // same secret code sender of message. // // command takes following post parameters: // // - user_id: unique identifier. must string of 40 hexadecimal characters. // - text: message text. must utf-8 string of maximum 190 bytes. // function handlemessage() { $userid = $this->getuserid(); /*$text = $this->getstring('text', self::max_message_length, true);*/ // first, record sender of message // active_users table. gives nickname, device token, , // secret code user. $stmt = $this->pdo->prepare('select * active_users user_id = ? limit 1'); $stmt->execute(array($userid)); $user = $stmt->fetch(pdo::fetch_obj); if ($user !== false) { // put sender's name , message text json payload // push notification. $payload = $this->makepayload($user->nickname/*, $text*/); // find device tokens other users registered // secret code. exclude device token of sender // of message, not push notification. // exclude users have not submitted valid device token yet. $stmt = $this->pdo->prepare("select device_token active_users secret_code = ? , device_token <> ? , device_token <> '0'"); $stmt->execute(array($user->secret_code, $user->device_token)); $tokens = $stmt->fetchall(pdo::fetch_column); // send out push notification each of these devices. foreach ($tokens $token) { $this->addpushnotification($token, $payload); } } } // retrieves user identifier post data. if user_id not // appear valid, script exits error message. function getuserid() { if (!isset($_post['user_id'])) exitwithhttperror(400, 'missing user_id'); $userid = trim(urldecode($_post['user_id'])); if (!$this->isvaliduserid($userid)) exitwithhttperror(400, 'invalid user_id'); return $userid; } // checks whether format of user identifier correct (40 hex // characters or 32 simulator). function isvaliduserid($userid) { if (strlen($userid) != 40 && strlen($userid) != 32) // 32 simulator return false; if (preg_match("/^[0-9a-fa-f]+$/", $userid) == 0) return false; return true; } // retrieves device token post data. if token not // appear valid, script exits error message. function getdevicetoken($maybeempty = false) { if (!isset($_post['token'])) exitwithhttperror(400, 'missing device token'); $token = trim($_post['token']); // "join" command allows token value of "0" specified, // necessary in case client did not yet obtain device // token @ point. allow such clients join, // not receive notifications until provide valid token // using "update" command. if ($maybeempty && $token == "0") return $token; if (!$this->isvaliddevicetoken($token)) exitwithhttperror(400, 'invalid device token'); return $token; } // checks whether format of device token correct (64 hexadecimal // characters). note: have no means verify whether device token // issued apns , corresponds actual device. function isvaliddevicetoken($devicetoken) { if (strlen($devicetoken) != 64) return false; if (preg_match("/^[0-9a-fa-f]{64}$/", $devicetoken) == 0) return false; return true; } // looks in post data field given name. if field // not valid utf-8 string, or long, script exits // error message. function getstring($name, $maxlength, $allownewlines = false) { if (!isset($_post[$name])) exitwithhttperror(400, "missing $name"); $string = trim($_post[$name]); if (!isvalidutf8string($string, $maxlength, $allownewlines)) exitwithhttperror(400, "invalid $name"); return $string; } // creates json payload push notification message. "alert" // text has following format: "sender_name: message_text". recipients // can obtain name of sender parsing alert text // first colon followed space. function makepayload($sendername, $text) { // convert nickname of sender json , truncate maximum // length of 20 bytes (which may less 20 characters). $namejson = $this->jsonencode($sendername); $namejson = truncateutf8($namejson, 20); // convert , truncate message text $textjson = $this->jsonencode($text); $textjson = truncateutf8($textjson, self::max_message_length); // combine json string $payload = '{"aps":{"alert":"' . $namejson . ': zapped live picture of you. tap message zap them back. ' . $textjson . '","sound":"beep.caf"}}'; return $payload; } // don't use php's built-in json_encode() function because converts // utf-8 characters \uxxxx. eats 6 characters in payload // no reason, json supports utf-8 fine. function jsonencode($text) { static $from = array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'); static $to = array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'); return str_replace($from, $to, $text); } // adds push notification push queue. notification not // sent immediately. server runs separate script, push.php, // periodically checks new entries in database table , sends // them apns servers. function addpushnotification($devicetoken, $payload) { // payloads have maximum size of 256 bytes. if payload // large (which shouldn't happen), won't send notification. if (strlen($payload) <= 256) { $stmt = $this->pdo->prepare('insert push_queue (device_token, payload, time_queued) values (?, ?, now())'); $stmt->execute(array($devicetoken, $payload)); } } } ?>
the above file has 4 main commands used in app via afnetworking join, update, leave, message
.
update
when users download app, inately register device tokens
- (void)application:(uiapplication*)application didregisterforremotenotificationswithdevicetoken:(nsdata*)devicetoken { nsstring* newtoken = [devicetoken description]; newtoken = [newtoken stringbytrimmingcharactersinset:[nscharacterset charactersetwithcharactersinstring:@"<>"]]; newtoken = [newtoken stringbyreplacingoccurrencesofstring:@" " withstring:@""]; nslog(@"my token is: %@", newtoken); }
notice nslog statement echoes out token in nslog this
this example method uses objective c
j son
, afnetworking
framework post token (and other paramaters) database using nsdictionary. update method. php counterpart can found in api.php
file above.
- (void)postupdaterequest { uinavigationcontroller *navigationcontroller = (uinavigationcontroller*)_window.rootviewcontroller; chatviewcontroller *chatviewcontroller = (chatviewcontroller*)[navigationcontroller.viewcontrollers objectatindex:0]; datamodel *datamodel = chatviewcontroller.datamodel; nsdictionary *params = @{@"cmd":@"update", @"user_id":[datamodel userid], @"token":[datamodel devicetoken]}; afhttpclient *client = [afhttpclient clientwithbaseurl:[nsurl urlwithstring:serverapiurl]]; [client postpath:@"/api.php" parameters:params success:nil failure:nil]; }
lastly, notice how device token gets inserted in database.
goal want add echo
statement php file above echo out device token. testing user icey
info can post database. thing is; no matter put echo statement, nothing shows or warning.
Comments
Post a Comment