เนื้อหาตอนนี้จะต้องจากตอนที่แล้ว จะเป็นการส่งค่าข้อมูลมาแสดง ด้วย php
ภาคต่อ สร้าง app ใช้งาน Push Notifications ใน phonegap ตอนที่ 10
https://www.ninenik.com/content.php?arti_id=586 via @ninenik
ในความเป็นจริง เราสามารถนำไปประยุกต์ได้หลากหลาย ขึ้นกับว่าจะใช้งานในรูปแบบไหน
แต่สำหรับในตัวอย่าง จะเป็นการเก็บข้อมูล regid ไว้ในฐานข้อมูลบน server
1. สร้างตารางฐานข้อมูลเก็บ regis
สร้าง ตาราง โดยมีโครงสร้าง ดังนี้
CREATE TABLE `regid` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `val` VARCHAR( 255 ) NOT NULL , `uid` VARCHAR( 100 ) NOT NULL , `datetime_add` DATETIME NOT NULL , `datetime_update` DATETIME NOT NULL , `regist` TINYINT( 1 ) NOT NULL ) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_unicode_ci;
เอาคำสั่ง sql ด้านบนไป รันได้เลย
2. สร้างไฟล์ php สำหรับบันทึก และอัพเดทค่า regid
ใช้ชื่อ add_regist.php
<?php header("Content-type:text/html; charset=UTF-8"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); // เชื่อมต่อกับฐานข้อมูล $link=mysql_connect("localhost","root","test"); // เชื่อมต่อ Server mysql_select_db("test"); // ติดต่อฐานข้อมูล mysql_query("set character set utf8"); // กำหนดค่า character set ที่จะใช้แสดงผล if(isset($_POST['uid']) && $_POST['uid']!="" && isset($_POST['regid']) && $_POST['regid']!=""){ $id_reg=@mysql_result(@mysql_query(" SELECT id FROM regid WHERE uid='".$_POST['uid']."' "),0,0); if($id_reg>0){ @mysql_query(" UPDATE regid SET val='".$_POST['regid']."', datetime_update=''".$_POST['datetime']."' WHERE uid='".$_POST['uid']."' "); echo 2; }else{ @mysql_query(" INSERT INTO regid( id,val,uid,datetime_add,datetime_update,regist )VALUES( NULL,'".$_POST['regid']."','".$_POST['uid']."','".$_POST['datetime']."','".$_POST['datetime']."','1' ) "); echo 1; } }else{ echo 0; } ?>
อัพไฟล์นี้ไว้ที่ฝั่ง server เราจะใช้ในการอัพเดท และเพิ่ม regid ของอุปกรณ์มือถือ
ที่ติดตั้ง app เพื่อเก็บค่าไว้ใช้ในการส่งข้อความ push notification ไปยังเครื่องนั้นๆ
3. ปรับแต่งโค้ดไฟล์ index.html
ปรับโค้ดนิดหน่อย เพื่อให้ทำการส่งค่า uid regid และค่าที่จำเป็นอื่นๆ ไปยังไฟล์ add_regist.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Push</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> </head> <body> <br><br> <div class="container-fluid"> <pre> <div id="home"> <div id="app-status-div"> <ul id="app-status-ul"> <li>Cordova PushNotification Plugin Demo</li> </ul> </div> </div> </pre> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script src="http://momentjs.com/downloads/moment.min.js"></script> <script type="text/javascript" src="cordova.js"></script> <script type="text/javascript"> $(function(){ }); </script> <script type="text/javascript"> var pushNotification; var php_addRegist="http://www.example.com/add_regist.php"; // path ไฟล์ function onDeviceReady() { //ฟังก์ชั่นทำงานเมื่อเครื่องพร้อม var data_uid=device.uuid; // เก็บค่า uid // แสดงข้อความถึง event ที่เกิดขึ้น ส่วนนี้ ใช้งานจริง สามารถลบออกได้ $("#app-status-ul").append('<li>deviceready event received</li>'); $("#app-status-ul").append('<li>UID'+data_uid+'</li>'); // แสดงค่า uid // ส่วนนี้ไม่เกี่ยวโดยตรงสักเท่าไหร่ แต่ประยุกต์ได้ เป็น event เมื่อกดปุ่ม back ที่เครื่อง document.addEventListener("backbutton", function(e){ $("#app-status-ul").append('<li>backbutton event received</li>'); // ถ้าหน้านี้มี div id เท่ากับ home แล้วถ้ากดปุ่ม back ให้ทำอะไร if( $("#home").length > 0){ // ใน commnet ด้านล่าง เขาแนะนำว่า เราอาจจะยกเลือกการ register เมื่อ // เกิดขึ้นในกรณีตามกล่าวข้างต้น // call this to get a new token each time. don't call it to reuse existing token. //pushNotification.unregister(successHandler, errorHandler); e.preventDefault(); navigator.app.exitApp(); //ปิด app ถ้าอยู่หน้า home }else{ navigator.app.backHistory(); // ย้อนกลับแบบปกติ ถ้าอยู่หน้าอื่น } }, false); try{ // เรียกใช้งาน plugin push pushNotification = window.plugins.pushNotification; $("#app-status-ul").append('<li>registering ' + device.platform + '</li>'); if(device.platform == 'android' || device.platform == 'Android' || device.platform == 'amazon-fireos' ) { pushNotification.register(successHandler, errorHandler, { // ทำการลง register "senderID":"xxxxxxxxxxxxxx", // เปลี่ยนเป็นค่า project name จาก phonegap ตอนที่ 9 "ecb":"onNotification" }); // required! } }catch(err){ // กรณีเกิดข้อผิดพลาด txt="There was an error on this page.\n\n"; txt+="Error description: " + err.message + "\n\n"; alert(txt); } } // จัดการกับข้อ GCM notifications สำหรับ Android function onNotification(e) { // แสดงสถานะ ใช้งานจริง ตรงนี่ิตัดออกได้ $("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>'); switch( e.event ){ // การทำงานกับเงื่อนไขเหตุการณ์ที่เกิดขึ้น case 'registered': // มีมีการ registered if( e.regid.length > 0 ){ // มีค่า regid // ข้อความแสดงสถานะการทำงาน ใช้งานจริง ตรงนี่ิตัดออกได้ $("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>"); // ทดสอบดูค่า regiid ใช้งานจริงปรับได้ตามต้องการ console.log("regID = " + e.regid); // ส่งค่า regid และ uid ไปบันทึกไว้บน server $.post(php_addRegist,{ uid:device.uuid, // คล้าย id เครื่องเรา regid:e.regid, datetime:moment().format('YYYY-MM-DD HH:mm:ss') },function(data){ alert(data); // ทำงานตามต้องการ ในที่นี้ทดสอบ ให้ alert ค่าที่ได้จากไฟล์ add_regist.php }); } break; case 'message': // เมื่อได้รับข้อความ push // ถ้าเราเปิด app อยู่ หมายถึง กำลังใช้งาน app จะให้ทำอย่างไร if (e.foreground){ // ใสคำสั่งส่วนนี้ตามต้องการ ในตัวอย่าง เขาจะบอกแค่สถานะว่า เป็นการแจ้งแบบ inline $("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>'); }else{ // กรณีอื่นๆ หรือก็คือ เมื่อมี push มา if(e.coldstart){ // แล้วเรากดที่ ข้อความ push ด้านบน // ก็จะเข้ามาทำงานในส่วนนี้ กำหนดตามต้องการ $("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>'); }else{ // กรณีอื่นๆ เช่น ทำงานแบบ background $("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>'); } } // แสดงข้อความ e.payload.message คือค่าข้อความทีเราได้ เราสามารถส่งตัวแปร อื่นๆ ตามต้องการได้ // ส่วนนี้ทำงานเม่อได้รับข้อความ push $("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>'); break; case 'error': // กรณี error $("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>'); break; default: // อื่นๆ $("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>'); break; } } // ฟังก์ชั่นเมื่อ process สำเร็จ function successHandler (result) { // เวลาใช้งานจริง บรทดัต่อจากนี้สามารถตัดออกได้ หรือใช้กำหนดค่าอื่นตามต้องการได้ $("#app-status-ul").append('<li>success:'+ result +'</li>'); } // ฟังก์ชั่นเมื่อ process เกิดข้อผิดพลาด function errorHandler (error) { // เวลาใช้งานจริง บรทดัต่อจากนี้สามารถตัดออกได้ หรือใช้กำหนดค่าอื่นตามต้องการได้ $("#app-status-ul").append('<li>error:'+ error +'</li>'); } // ให้ไปทำงานฟังก์ชัน onDeviceReady เมือ cordova โหลดเรียบร้อยแล้ว document.addEventListener('deviceready', onDeviceReady, true); </script> </body> </html>
พอกำหนดตามตัวอย่าง และปรับแก้ในส่วนของ path ไฟล์ ไปที่ server ของเรา
และ กำหนด project number ให้กับ senderID แล้วก็ save แล้ว build android
สร้างไฟล์ apk แล้วนำไปติดตั้ง จากนั้งก็เปิด app ดูการทำงาน
ถ้าไม่มีอะไรผิดพลาด จะมีการส่งค่าไปบันทึกที่ ตารางที่เราทำไว้ และพร้อมแล้วจะทำการส่งค่า
4. ตอนสุดท้าย การส่งข้อความ push notification ด้วย php
ส่วนนี้เราจะทำที่ server ของเรา สร้างไฟล์ pusher.php โค้ดตามดานล่างเลย
หรือดาวน์โหลดได้ที่ https://www.ninenik.com/download/pusher.rar
หรือดาวน์โหลดได้ที่ https://www.ninenik.com/download/pusher.rar
<?php class Pusher { const GOOGLE_GCM_URL = 'https://android.googleapis.com/gcm/send'; private $apiKey; private $proxy; private $output; public function __construct($apiKey, $proxy = null) { $this->apiKey = $apiKey; $this->proxy = $proxy; } /** * @param string|array $regIds * @param string $data * @throws Exception */ public function notify($regIds, $data) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, self::GOOGLE_GCM_URL); if (!is_null($this->proxy)) { curl_setopt($ch, CURLOPT_PROXY, $this->proxy); } curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders()); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, $this->getPostFields($regIds, $data)); $result = curl_exec($ch); if ($result === false) { throw new Exception(curl_error($ch)); } curl_close($ch); $this->output = $result; } /** * @return array */ public function getOutputAsArray() { return json_decode($this->output, true); } /** * @return object */ public function getOutputAsObject() { return json_decode($this->output); } private function getHeaders() { return array('Authorization: key=' . $this->apiKey,'Content-Type: application/json'); } private function getPostFields($regIds, $data) { $fields = array( "registration_ids" => is_string($regIds) ? array($regIds) : $regIds, "data"=> is_string($data) ? array('message' => $data) : $data, ); return json_encode($fields, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE); } } ?>
จากนั้นสร้างไฟล์ test_push.php โค้ดตามด้านล่าง
<?php header("Content-type:text/html; charset=UTF-8"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); // เชื่อมต่อกับฐานข้อมูล $link=mysql_connect("localhost","root","test"); // เชื่อมต่อ Server mysql_select_db("test"); // ติดต่อฐานข้อมูล mysql_query("set character set utf8"); // กำหนดค่า character set ที่จะใช้แสดงผล // ส่วนตั้งค่าการใช้งาน push include("pusher.php"); $apiKey = "xxxxxx"; // ค่าา api key จาก phonegap ตอนที่ 9 $pusher = new Pusher($apiKey); $regId=array(); $q=" SELECT * FROM regid "; $qr=mysql_query($q); while($rs=mysql_fetch_assoc($qr)){ $regId[]=$rs['val']; } // prep the bundle $msg = array ( 'message' => 'ทดสอบ', 'title' => 'Push', ); $pusher->notify($regId, $msg); echo "<pre>"; print_r($pusher->getOutputAsArray()); echo "</pre>"; ?>
apiKey คือค่าที่ได้จาก ตอนที่ 9 ให้เอาค่านั้นมาใส่แทนลงไป
แก้ไขการตั้งค่าการติดต่อกับฐานข้อมูลให้ถูกต้อง
จากโค้ด ก็คือการไปดึงค่า regid จากฐานข้อมูล มาเก็บไว้ในตัวแปร
จากนั้น ก็จะใช้คำสั่ง ส่งข้อความ push ไปยังเครื่องที่มี regid ที่เราได้จากฐานข้อมูล
วิธีการทำสอบ ก็ให้อัพไฟล์นี้ขึ้น server แล้วกด รีเฟรส หร็อ รันไฟล์
ถ้าไม่มีข้อผิดพลาด ก็ จะได้รับข้อความเป็น push notification ที่เครื่องมือถือของเรา
เท่าที่รู้ เราสามารถส่งได้พร้อมกันสูงสุด 1000 regid
ทั้งหมดนี้เป็นแนวทาง เราสามารถนำไปประยุกต์เพิ่มเติม เช่น สร้างฟอร์ม สำหรับกรอก
ข้อมูล และให้ทำการส่งข้อมูล เมื่อ กดปุ่ม submit ในฟอร์ม แบบนั้นก็ได้
Good Luck พยายามทำตามขั้นตอนอย่างละเอียด เพื่อให้ไม่เกิดข้อผิดพลาด