KaderTarlan

BlogCan

GCM Ile Push Notification

Merhaba arkadaşlar bir cihaza Push Notification yapmak istediğimiz zaman Google Cloud Messaging dediğimiz servisi kullanıyoruz. Kısaca GCM olan bu servis , sunucu görevi gören bilgisayarımızdan göndereceğimiz verinin , android cihaz tarafından alınmasını sağlayacak bir teknolojidir. Bulut teknolojisi kullanarak uygulamara veri göndermeyi sağlar.

Android cihazımızda bir uygulamamız olduğunu farz edelim bu uygulama bize tatile çıktığımız zaman konum bilgimize erişip bize otel adları sunsun ve push notification mantığı ile çalışsın. O civarda otel arıyor olalım ve hareket etiiğimizi anlayan bu uygulama konum bilgimize erişsin. Biz bu uygulamaya sürekli otel var mı diye sormayalım da o bulunduğumuz yerde otel bulduğunda push notification ile bize otel adlarını yollasın.

Eğer uygulamamızda push notification yoksa bizim sürekli sormamız gerekecekti yeni otel buldun mu diye. Bu durum ayrıca zahmet ve serverımızda sürekli bir yogunluğa neden olur.
Fakat bizim uygulamamız GCM ile çalışıyor ve bana çok güzel kolaylık sunuyor. Biz sürekli sayfa güncelleyip sormadan uygulama bizim işimizi görecek ne kadar kolay değil mi ?

Uygulamalara bu push notification olayını yerleştirdiğimiz zaman istediğimiz kullanıcıya istediğimiz mesajı atarak kullanıcıyı uyarabiliyoruz.
Bankalar örneğin böyle bir uygulama kullansa bakiyesi eksiye inen kullanıcılarını tespit etse ve onlara otomatik push notification ile mesaj atsa Paraya ihtiyacın mı var dese çok da güzel olur.

Push Notification ile bir android cihazımıza bildirim yollamak isteyelim bunun için bize bir android uygulaması lazım. Bir diğer olay GCM servisi lazım ve Sunucumuzun olması lazım.
GCM çalşma mantığı ise aşağıdaki resimdeki gibidir.

  • Ilk adımda android uygulaması application_id and sender_id bilgilerimizi GCM ile paylasır. GCM sunucusuda bu bilgileri tutar.

  • Ikinci adımda GCM sunucu uygulamasından register_id bilgisi gelir, bu bilgi gelen application_id and sender_id bilgilerini kullanarak uygulamayı register ettikten sonra oluşur.

  • Mobil uygulama GCM sunucusundan aldığı register_id bilgisini push notification yapacağı servera iletir.

  • Server da gelen bu regıster_id bilgisini kendi veritabanına kaydeder.

  • Server kendi application_id si için göndereceği bilgileri GCM'e registration_id olarak bildiriyor.

  • GCM de bu registration_id üzerinden belirlenen mobil cihaza serverdan gelen bilgiyi iletiyor.

Tüm bu adımların tamamı bahsettiğimiz push notification işlemini gerçekleştiriyor.

Ilk Adım;

Google Cloud Messaging dediğimiz servisi kullanabilmemiz için Google Developer Console girip hesap oluşturmamız gerekiyor. Create New Project e tıklıyoruz. Açılan sayfaya bilgileri giriyoruz (name,id). GCM ile paylaştığımız application_id olur bu.

Projemizi oluşturduktan sonra;
Menuden APİs&AUTH menüsünden Credentials seciyoruz. Açılan sayfadan Create New Key tıklayıp Server Key seçiyoruz. Ve Create dıyoruz. Gelen ekranda APi keyimizi göreceksiniz bunu kullanacağımız yerler olacak bu şekilde bunu da oluşturmuş olduk.

İkinci Adım;

Veritabanını Oluşturma

Bunun için phpMyAdmin kullanacağız. Web uygulamalarını kendi bilgisayarınızda test edebilmek için sisteminizde LAMP (Linux, Apache, MySQL, PHP) server kurulu olmalıdır. buradan LAMP kurulumu gerçekleştirebilirsiniz.

Kurulumu tamamladıktan sonra http://localhost/phpmyadmin adresine giriş yapabilirsiniz. Giriş yaptıktan sonra GCM adında database oluşturuyoruz.Daha sonra SQL tıklayıp aşağıdaki kodu çalıştırdığımızda gcm_users adında bir tablo oluşturmuş oluruz.

1
2
3
4
5
6
7
8
 CREATE TABLE IF NOT EXISTS `gcm_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `gcm_regid` text,
  `android_id` varchar(50) NOT NULL,
  `email` varchar(255) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
 )ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

PHP Projelerini Oluşturma

Veritabanını oluşturduktan sonra php konfigurasyon dosyalarını oluşturmalıyız.

İlk önce veritabanı bilgilerinin yer aldığı config.php dosyası oluşturalım ve aşağıdaki kodu ekleyelim.

config.php

1
2
3
4
5
6
7
8
9
10
<?php
 //Database config degiskenleri
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASSWORD", "root_password");
define("DB_DATABASE", "gcm");

 //Projemizi oluştururken elde ettiğimiz API keye yazıyoruz
define("GOOGLE_API_KEY", "AIzaSyBuKjAAFTPaYIL83BvKzhfJ1patQfojz-w");
?>

Şimdi ikinci bir dosya oluşturuyoruz db_connect.php adında burada da database bağlantımız sağlanacak.

db_connect.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
 class DB_Connect {

     //constructor
    function __construct() {}

     //destructor
    function __destruct() {}

     //database bağlantısı
    public function connect() {
        //config.php dosyamızı dahil ediyoruz
        require_once 'config.php';
        //config.php dosyamızdaki bilgiler eşliğinde mysql bağlanıyoruz.
        $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
        //databasemizi seçiyoruz
        mysql_select_db(DB_DATABASE);

        return $con;
    }
    //database bağlantısı kesiliyor
    public function close() {
        mysql_close();
    }
  }
?>

Üçüncü dosyamız oluşturduğumuz veritabanında CRUD işlemleri gerçekleştirmek için db_functions.php adında bir dosya olacak ve bu dosya içine kullanıcı oluşturmak için bir fonksiyon yazıyoruz fazlasını yapmakda mümkün.

db_functions.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php

class DB_Functions {

    private $db;

    //yapıcı kodumuzu yerleştiriyoruz.
    function __construct() {
        //oluşturduğumuz database bağlantısını çağırıyoruz.
        include_once './db_connect.php';
        //database bağlantısı oluşturuldu
        $this->db = new DB_Connect();
        $this->db->connect();
   }

    function __destruct() {}

    // CRUD işlemlerinden Create ile yeni bir kullanıcı ekleme işlemi yapılıyor
    public function storeUser($name, $email, $gcm_regid) {
        // database kullanıcı ekleme
        $result = mysql_query("INSERT INTO gcm_users(name, email, gcm_regid, created_at) VALUES('$name', '$email', '$gcm_regid', NOW())");
        // kullanıcı eklenmiş mi kontrol ediyoruz
        if ($result) {
            // kullanıcı bilgilerine erişiyoruz
            $id = mysql_insert_id(); // en son eklenen id
            $result = mysql_query("SELECT * FROM gcm_users WHERE id = $id") or die(mysql_error());
            // kullanıcı bilgilerine geri dönüyoruz
            if (mysql_num_rows($result) > 0) {
                return mysql_fetch_array($result);}
            else {
                return false; }  }
        else {
            return false;}
    }

    // Tüm kullanıcılara erişme 
    public function getAllUsers() {
        $result = mysql_query("select * FROM gcm_users");
        return $result;
    }}

?>

Dördüncü oluşturacağımız dosya GCM.php olacak. Bu dosya GCM sunucuya push bildirim istekleri göndermek için kullanılır.

GCM.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

  <?php
 class GCM {
    // constructor
    function __construct() {}

    //Push notification yollama, resmimizdeki 5. adım
     // yollanacak registerin idisi ve mesajımız burada kullanılacak

    public function send_notification($registatoin_ids, $message) {
        // ilk oluşturduğumuz database bilgimizin olduğu config.php dosyasını cağırıyoruz.
        include_once './config.php';

        // adresimize gidiyoruz ardından ulaşılmasını istediğimiz cihazın register_id bilgisini ve mesajımızı buraya yerleştiriyoruz.
        $url = 'https://android.googleapis.com/gcm/send';

        $fields = array(
            'registration_ids' => $registatoin_ids,
            'data' => $message,
        );

        $headers = array(
            'Authorization: key=' . GOOGLE_API_KEY,
            'Content-Type: application/json'
        );
        // bağlantımızı açtık
        $ch = curl_init();

        // urlyi set ettik ve POST data
        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        // SSL Certificate
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

        //post çalıştırılıyor
        $result = curl_exec($ch);
        if ($result === FALSE) {
            die('Curl failed: ' . curl_error($ch));
        }

        // Close connection
        curl_close($ch);
        echo $result;
    }}
?>

Beşinci oluşturacağımız dosya Register.php dosyası , Bu dosya Android cihazından gelen istekleri alır. Android cihazınızdan Adınız, Mailiniz ve bir Register_id niz ile ki bu id size ilk GCM kayıt olurken verildi, seni bu id ile kayıt ettim demişti GCM.
Bizde bunları kullanarak Böylece uygulamaya dahil olduk bilgilerimizde database aktarıldı, yazdığın register_id bilgisi de database tablomuzdaki Reg_id bilgisine eşitlenir. Aynı zamanda buradaki reg_id bilgimizi GCM.php dosyamıza da yolladık oluşturduğumuz bir mesajla birlikte. GCM.php bu reg_id sine ait cihaza bu mesajı push etmek için GCM servera bağlanacak.

register.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 <?php

  // response json
  $json = array();

  //Kullanıcı cihazını kayıt eder,register eder
    ve bunu kullanıcı tablosundaki reg_id depolar

if (isset($_POST["name"]) && isset($_POST["email"]) && isset($_POST["regId"])) {
    $name = $_POST["name"];
    $email = $_POST["email"];
    $gcm_regid = $_POST["regId"]; // GCM Registration ID

    //kullanıcı bilgilerini database yazıyor, 
    //Bunu da bilgileri alıp yazdığımız db_functions.php dosyasını kullanarak yapıyor
    include_once './db_functions.php';
    include_once './GCM.php';

    $db = new DB_Functions();
    $gcm = new GCM();

    $res = $db->storeUser($name, $email, $gcm_regid);

    $registatoin_ids = array($gcm_regid);
    $message = array("product" => "shirt");

    $result = $gcm->send_notification($registatoin_ids, $message);

    echo $result;
}
  else {}
?>

Altıncı olarak oluşturacağımız dosya send_message.php dosyası , Bu dosya da reg_id ve mesaage bilgilerimizi alıp notification yapması için GCM.php dosyasını çağırır.

send_message.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  <?php
  if (isset($_GET["regId"]) && isset($_GET["message"])) {
     $regId = $_GET["regId"];
     $message = $_GET["message"];

     include_once './GCM.php';

     $gcm = new GCM();

     $registatoin_ids = array($regId);
     $message = array("price" => $message);

     $result = $gcm->send_notification($registatoin_ids, $message);

     echo $result;
}
?>

Son olarak oluşturacağımız dosya index.php dosyası, Bu dosya takip edilen kodları basar. Bu kodlar basit bir admin panel oluşturur , kullanıcı cihazlarını sıralar , bireysel kullanıcılara push notıfıcatıon yollar.

index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function(){

            });
            function sendPushNotification(id){
                var data = $('form#'+id).serialize();
                $('form#'+id).unbind('submit');
                $.ajax({
                    url: "send_message.php",
                    type: 'GET',
                    data: data,
                    beforeSend: function() {

                    },
                    success: function(data, textStatus, xhr) {
                          $('.txt_message').val("");
                    },
                    error: function(xhr, textStatus, errorThrown) {

                    }
                });
                return false;
            }
        </script>
        <style type="text/css">
            .container{
                width: 950px;
                margin: 0 auto;
                padding: 0;
            }
            h1{
                font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
                font-size: 24px;
                color: #777;
            }
            div.clear{
                clear: both;
            }
            ul.devices{
                margin: 0;
                padding: 0;
            }
            ul.devices li{
                float: left;
                list-style: none;
                border: 1px solid #dedede;
                padding: 10px;
                margin: 0 15px 25px 0;
                border-radius: 3px;
                -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
                -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
                box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
                font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
                color: #555;
            }
            ul.devices li label, ul.devices li span{
                font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
                font-size: 12px;
                font-style: normal;
                font-variant: normal;
                font-weight: bold;
                color: #393939;
                display: block;
                float: left;
            }
            ul.devices li label{
                height: 25px;
                width: 50px;
            }
            ul.devices li textarea{
                float: left;
                resize: none;
            }
            ul.devices li .send_btn{
                background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#0096FF), to(#005DFF));
                background: -webkit-linear-gradient(0% 0%, 0% 100%, from(#0096FF), to(#005DFF));
                background: -moz-linear-gradient(center top, #0096FF, #005DFF);
                background: linear-gradient(#0096FF, #005DFF);
                text-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
                border-radius: 3px;
                color: #fff;
            }
        </style>
    </head>
    <body>

    <?php
        include_once 'db_functions.php';
        $db = new DB_Functions();
        $users = $db->getAllUsers();
        if ($users != false)
            $no_of_users = mysql_num_rows($users);
        else
            $no_of_users = 0;
        ?>
        <div class="container">
            <h1>No of Devices Registered: <?php echo $no_of_users; ?></h1>
            <hr/>
            <ul class="devices">
                <?php
                if ($no_of_users > 0) {
                    ?>
                    <?php
                    while ($row = mysql_fetch_array($users)) {
                        ?>
                        <li>
                            <form id="<?php echo $row["id"] ?>" name="" method="post" onsubmit="return sendPushNotification('<?php echo $row["id"] ?>')">
                                <label>Name: </label> <span><?php echo $row["name"] ?></span>
                                <div class="clear"></div>
                                <label>Email:</label> <span><?php echo $row["email"] ?></span>
                                <div class="clear"></div>
                                <div class="send_container">                               
                                    <textarea rows="3" name="message" cols="25" class="txt_message" placeholder="Type message here"></textarea>
                                    <input type="hidden" name="regId" value="<?php echo $row["gcm_regid"] ?>"/>
                                    <input type="submit" class="send_btn" value="Send" onclick=""/>
                                </div>
                            </form>
                        </li>
                    <?php }
                } else { ?>
                    <li>
                        No Users Registered Yet!
                    </li>
                <?php } ?>
            </ul>
        </div>
    </body>

Son olarak yaptığımız bu uygulamayı şimdilik bağlı bir Cihazımız olmadığı için bir test.php dosyamız ile Adımızı, Mailimizi ve Random bir Reg_id vererek kayıt işlemlerinin nasıl gerçekleştiğini görelim.

test.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 <!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function(){
            });
        </script>
    </head>
    <body>
        <form name="" method="post" action="register.php">
         <input type="text" name="name"/>
         <input type="text" name="email"/>
         <input type="text" name="regId"/>
         <input type="submit"/>
     </form>
    </body>
</html>

Şimdi çalıştırma zamanı!
Kurulumunu gerçekleştirdiğiniz LAMP ile uygulamarımızı kendi bilgisayarımızda test etmek mümkün demiştik. Bunun için benim bilgisayarım için uzantısı /var/www/html/ olan dizinimin altına tüm bu dosyalarımın olduğu GCM adlı dizinimi yerleştiriyorum. Yeni dizinim /var/www/html/GCM oluyor.

Browsera gelip http://localhost/GCM/ dediğimiz zaman çıkan ekran;

Şimdi bir cihaz bağlıyormuşuz gibi test.php dosyamızı çalıştıralım.
Bunun için http://localhost/GCM/test.php adresine girelim ve bir ad, mail, reg_id bilgisi girelim.
http://localhost/GCM/ adresini tekrar kontrol edelim.

Gördüğünüz gibi bir cihaz eklendi index.php dosyamıza. Burada eklenen cihazlar sıralanır. Ve push bildirimlerimizi mesaj kısmına yazıp send dediğimizde o cihazlara bildirim gitmiş olur.

Bu arada Database de durumlar ne oldu derseniz? O halde ekran görüntüsünü paylaşayım sizinle;

Gördüğünüz gibi girdiğimiz Ad, Mail ve Reg_id bilgileri otomatik olarak oraya kayıt oldu.

Yazımı burada bitireceğim , sonraki aşamada Gerçek bir android cihaz bağlayıp uygulamamıza gerçek bir notification yollayacağız.
İyi çalışmalar.