Google Cloud Messaging allows you send lightweight messages from the backend server to all the devices whenever there is new data available. This saves lot of user’s battery by avoiding poll request to server for new data. Using GCM you can build powerful multi platform (iOS, Android & Web) apps like real time chat, news feed, cloud storage and lot more. On top of everything, GCM is completely free and there are no limitations.

As parse.com announced their shutdown recently, GCM is the only best option even though it won’t comes with an admin interface. But don’t worry, we’ll build a simple admin panel in this article.

android realtime chat app using gcm php mysql

As this article is pretty lengthy, I have divided it into 3 parts. Each part covers a unique part in building the final realtime chat app.

Part 1: Covers building the REST API for chat app including the GCM server app.

Part 2: Explains integrating GCM into your android app including a test message.

Part 3: Building Simple Realtime Chat App.

1. Google Cloud Messaging

Typically GCM implementation involves three components. Google cloud messaging server, the app server and the client app. We should take care of writing the app server and the client app. In order to make calls from the app server to GCM server, you can follow HTTP or XMPP protocol. HTTP supports downstream (gcm to client) messages only. XMPP supports both downstream and upstream (device to gcm, then from gcm to server) messages.

Below is the pictorial representation of the overall architecture.

android-google-cloud-messaging-architecture

1. First the app connects to GCM server and register itself.

2. Upon successful registration, GCM issues gcm registration token to device. This registration token uniquely identifies each device.

3. The device sends the registration token to our server to store it in MySQL.

4. Whenever app server wants to send push notification, it sends a request to GCM server sending the push message along with the registration token.

5. GCM server identifies the device using the registration token and initiates the push message.

6. The device receives the push messages and further action takes place.

2. Obtaining Google API Key

Google API key is necessary to interact with GCM server. GCM uses this key to identify your server app. Follow the below steps to obtain your API key. Note that the developer console interface is changing more frequently. So, the below steps may vary in future.

1. Goto Google developers console and create a new app. If you have already created one, select the app.

2. Give a name to your new project. Once the project is created, goto project’s dashboard and click on Use Google APIs

3. Under Mobile APIs, click on Cloud Messaging for Android and enable the API by clicking on top enable API button.

4. Once enabled, click on Credentials on the left. You will be asked to create new credentials by showing multiple options. Choose API Key and then Server Key.

5. After choosing Server Key, your API key will be displayed on the dashboard. Note down the API key as we need to use it in our PHP project.

3. Building Simple Realtime Chat App

In this article, we are going to learn how to create a simple realtime chat app by using Android, GCM, PHP, MySQL, HTML & CSS. We use HTML & CSS to build the admin panel for the server app.

Below are the screens of the android app.

android-simple-chat-app-using-gcm-php-mysql

And the server app comes with the option of choosing the user(s) / topic and send the push notification.

android-php-mysql-gcm-chat-app-admin-panel

This part of the article involves building the server app including designing the MySQL database, REST API for mobile app and an admin panel to send push notifications. I am using Netbeans IDE to develop the PHP code and WAMP / MAMP server to create the php, mysql environment.

Now let’s start designing the database first.

4. Designing MySQL Database

For this app we need only three tables. users, chat rooms and messages.

users – This table holds the user information like name, email and other profile information along with gcm registration id.

chat_rooms – Contains the chat room information.

messages – Contains the messages sent in the chat rooms.

android-simple-chat-app-mysql-database

Open phpmyadmin and execute the below sql query to create the required database and tables.

CREATE DATABASE gcm_chat;

CREATE TABLE `chat_rooms` (
  `chat_room_id` int(11) NOT NULL,
  `name` varchar(100) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

CREATE TABLE `messages` (
  `message_id` int(11) NOT NULL,
  `chat_room_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `message` text NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `users` (
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `gcm_registration_id` text NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `chat_rooms`
  ADD PRIMARY KEY (`chat_room_id`);

ALTER TABLE `messages`
  ADD PRIMARY KEY (`message_id`),
  ADD KEY `chat_room_id` (`chat_room_id`),
  ADD KEY `user_id` (`user_id`),
  ADD KEY `chat_room_id_2` (`chat_room_id`);

ALTER TABLE `users`
  ADD PRIMARY KEY (`user_id`),
  ADD UNIQUE KEY `email` (`email`);

ALTER TABLE `messages`
  ADD CONSTRAINT `messages_ibfk_3` FOREIGN KEY (`chat_room_id`) REFERENCES `chat_rooms` (`chat_room_id`),
  ADD CONSTRAINT `messages_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;

5. Creating PHP REST API

I am using Slim framework to create the REST endpoints. If you are not aware of PHP Slim, refer my previous tutorial REST API for Android app using PHP, Slim and MySQL to understand how easily you can create the REST API endpoints for your android app.

Below is the project structure of the PHP app. You have to make sure that you are following same structure while following the further steps.

gcm-simple-chat-app-php-mysql-project

include – Contains the database classes to perform CRUD operations on the database.

libs – Contains the libraries needed for the app (slim, gcm)

v1 – Root directory of the REST API

index.php, demo.php, styles.css – Required to create the admin interface.

1. Goto your WAMP/MAMP installation location and open the web directory. On windows, it will be c:/wamp/www directory. On Mac, the path will be /Applications/MAMP/htdocs.

2. Inside the web directory (www or htdocs), create a directory named gcm_chat. This will be the root directory of our project.

3. Inside gcm_chat folder, create the remaining directories as shown in the above image. Create folders named include, libs and v1. Inside libs, create another folder named gcm.

4. Download Slim framework and paste it inside libs folder.

5. Create a file named config.php in include. This file contains the app configuration like database credentials, google API Key and other information.

Replace GOOGLE_API_KEY with your API Key which you obtained in 2nd section. Also keep the correct database credentials.

<?php
/**
 * Database configuration
 */
define('DB_USERNAME', 'root');
define('DB_PASSWORD', 'root');
define('DB_HOST', 'localhost');
define('DB_NAME', 'gcm_chat');

define("GOOGLE_API_KEY", "AIzaSyDKk_Ew7Vi4FZnMzu6GCY5PLb4xZG8muvX");

// push notification flags
define('PUSH_FLAG_CHATROOM', 1);
define('PUSH_FLAG_USER', 2);

?>

6. Create a file named db_connect.php inside include folder. This class takes care of database connection.

<?php

/**
 * Handling database connection
 *
 */
class DbConnect {

    private $conn;

    function __construct() {        
    }

    /**
     * Establishing database connection
     * @return database connection handler
     */
    function connect() {
        include_once dirname(__FILE__) . '/config.php';

        // Connecting to mysql database
        $this->conn = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);

        // Check for database connection error
        if (mysqli_connect_errno()) {
            echo "Failed to connect to MySQL: " . mysqli_connect_error();
        }

        // returing connection resource
        return $this->conn;
    }
}
?>

7. Create another file named db_handler.php inside include folder. This file contains all the necessary functions to interact with database tables.

<?php

/**
 * Class to handle all db operations
 * This class will have CRUD methods for database tables
 *
 * @author Ravi Tamada
 */
class DbHandler {

    private $conn;

    function __construct() {
        require_once dirname(__FILE__) . '/db_connect.php';
        // opening db connection
        $db = new DbConnect();
        $this->conn = $db->connect();
    }

    // creating new user if not existed
    public function createUser($name, $email) {
        $response = array();

        // First check if user already existed in db
        if (!$this->isUserExists($email)) {
            // insert query
            $stmt = $this->conn->prepare("INSERT INTO users(name, email) values(?, ?)");
            $stmt->bind_param("ss", $name, $email);

            $result = $stmt->execute();

            $stmt->close();

            // Check for successful insertion
            if ($result) {
                // User successfully inserted
                $response["error"] = false;
                $response["user"] = $this->getUserByEmail($email);
            } else {
                // Failed to create user
                $response["error"] = true;
                $response["message"] = "Oops! An error occurred while registereing";
            }
        } else {
            // User with same email already existed in the db
            $response["error"] = false;
            $response["user"] = $this->getUserByEmail($email);
        }

        return $response;
    }

    // updating user GCM registration ID
    public function updateGcmID($user_id, $gcm_registration_id) {
        $response = array();
        $stmt = $this->conn->prepare("UPDATE users SET gcm_registration_id = ? WHERE user_id = ?");
        $stmt->bind_param("si", $gcm_registration_id, $user_id);

        if ($stmt->execute()) {
            // User successfully updated
            $response["error"] = false;
            $response["message"] = 'GCM registration ID updated successfully';
        } else {
            // Failed to update user
            $response["error"] = true;
            $response["message"] = "Failed to update GCM registration ID";
            $stmt->error;
        }
        $stmt->close();

        return $response;
    }

    // fetching single user by id
    public function getUser($user_id) {
        $stmt = $this->conn->prepare("SELECT user_id, name, email, gcm_registration_id, created_at FROM users WHERE user_id = ?");
        $stmt->bind_param("s", $user_id);
        if ($stmt->execute()) {
            // $user = $stmt->get_result()->fetch_assoc();
            $stmt->bind_result($user_id, $name, $email, $gcm_registration_id, $created_at);
            $stmt->fetch();
            $user = array();
            $user["user_id"] = $user_id;
            $user["name"] = $name;
            $user["email"] = $email;
            $user["gcm_registration_id"] = $gcm_registration_id;
            $user["created_at"] = $created_at;
            $stmt->close();
            return $user;
        } else {
            return NULL;
        }
    }

    // fetching multiple users by ids
    public function getUsers($user_ids) {

        $users = array();
        if (sizeof($user_ids) > 0) {
            $query = "SELECT user_id, name, email, gcm_registration_id, created_at FROM users WHERE user_id IN (";

            foreach ($user_ids as $user_id) {
                $query .= $user_id . ',';
            }

            $query = substr($query, 0, strlen($query) - 1);
            $query .= ')';

            $stmt = $this->conn->prepare($query);
            $stmt->execute();
            $result = $stmt->get_result();

            while ($user = $result->fetch_assoc()) {
                $tmp = array();
                $tmp["user_id"] = $user['user_id'];
                $tmp["name"] = $user['name'];
                $tmp["email"] = $user['email'];
                $tmp["gcm_registration_id"] = $user['gcm_registration_id'];
                $tmp["created_at"] = $user['created_at'];
                array_push($users, $tmp);
            }
        }

        return $users;
    }

    // messaging in a chat room / to persional message
    public function addMessage($user_id, $chat_room_id, $message) {
        $response = array();

        $stmt = $this->conn->prepare("INSERT INTO messages (chat_room_id, user_id, message) values(?, ?, ?)");
        $stmt->bind_param("iis", $chat_room_id, $user_id, $message);

        $result = $stmt->execute();

        if ($result) {
            $response['error'] = false;

            // get the message
            $message_id = $this->conn->insert_id;
            $stmt = $this->conn->prepare("SELECT message_id, user_id, chat_room_id, message, created_at FROM messages WHERE message_id = ?");
            $stmt->bind_param("i", $message_id);
            if ($stmt->execute()) {
                $stmt->bind_result($message_id, $user_id, $chat_room_id, $message, $created_at);
                $stmt->fetch();
                $tmp = array();
                $tmp['message_id'] = $message_id;
                $tmp['chat_room_id'] = $chat_room_id;
                $tmp['message'] = $message;
                $tmp['created_at'] = $created_at;
                $response['message'] = $tmp;
            }
        } else {
            $response['error'] = true;
            $response['message'] = 'Failed send message';
        }

        return $response;
    }

    // fetching all chat rooms
    public function getAllChatrooms() {
        $stmt = $this->conn->prepare("SELECT * FROM chat_rooms");
        $stmt->execute();
        $tasks = $stmt->get_result();
        $stmt->close();
        return $tasks;
    }

    // fetching single chat room by id
    function getChatRoom($chat_room_id) {
        $stmt = $this->conn->prepare("SELECT cr.chat_room_id, cr.name, cr.created_at as chat_room_created_at, u.name as username, c.* FROM chat_rooms cr LEFT JOIN messages c ON c.chat_room_id = cr.chat_room_id LEFT JOIN users u ON u.user_id = c.user_id WHERE cr.chat_room_id = ?");
        $stmt->bind_param("i", $chat_room_id);
        $stmt->execute();
        $tasks = $stmt->get_result();
        $stmt->close();
        return $tasks;
    }

    /**
     * Checking for duplicate user by email address
     * @param String $email email to check in db
     * @return boolean
     */
    private function isUserExists($email) {
        $stmt = $this->conn->prepare("SELECT user_id from users WHERE email = ?");
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $stmt->store_result();
        $num_rows = $stmt->num_rows;
        $stmt->close();
        return $num_rows > 0;
    }

    /**
     * Fetching user by email
     * @param String $email User email id
     */
    public function getUserByEmail($email) {
        $stmt = $this->conn->prepare("SELECT user_id, name, email, created_at FROM users WHERE email = ?");
        $stmt->bind_param("s", $email);
        if ($stmt->execute()) {
            // $user = $stmt->get_result()->fetch_assoc();
            $stmt->bind_result($user_id, $name, $email, $created_at);
            $stmt->fetch();
            $user = array();
            $user["user_id"] = $user_id;
            $user["name"] = $name;
            $user["email"] = $email;
            $user["created_at"] = $created_at;
            $stmt->close();
            return $user;
        } else {
            return NULL;
        }
    }

}

?>

8. Now let’s start creating the files required for GCM. Create a file named gcm.php inside libs ⇒ gcm folder. This file contains necessary functions required to interact with GCM server. These functions basically makes a CURL request to GCM server by passing required parameters in order to invoke a push notification.

send() – Function sends push notification to a single user

sendToTopic() – Sends push notification to a topic

sendToMultiple() – Send push notification to multiple users

<?php
class GCM {

    // constructor
    function __construct() {
        
    }

    // sending push message to single user by gcm registration id
    public function send($to, $message) {
        $fields = array(
            'to' => $to,
            'data' => $message,
        );
        return $this->sendPushNotification($fields);
    }

    // Sending message to a topic by topic id
    public function sendToTopic($to, $message) {
        $fields = array(
            'to' => '/topics/' . $to,
            'data' => $message,
        );
        return $this->sendPushNotification($fields);
    }

    // sending push message to multiple users by gcm registration ids
    public function sendMultiple($registration_ids, $message) {
        $fields = array(
            'registration_ids' => $registration_ids,
            'data' => $message,
        );

        return $this->sendPushNotification($fields);
    }

    // function makes curl request to gcm servers
    private function sendPushNotification($fields) {

        // include config
        include_once __DIR__ . '/../../include/config.php';

        // Set POST variables
        $url = 'https://gcm-http.googleapis.com/gcm/send';

        $headers = array(
            'Authorization: key=' . GOOGLE_API_KEY,
            'Content-Type: application/json'
        );
        // Open connection
        $ch = curl_init();

        // Set the url, number of POST vars, 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);

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

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

        // Execute post
        $result = curl_exec($ch);
        if ($result === FALSE) {
            die('Curl failed: ' . curl_error($ch));
        }

        // Close connection
        curl_close($ch);

        return $result;
    }

}

?>

9. Under libs ⇒ gcm, create another file named push.php. This class prepares the required json format that is transferred as a push message to device. If you want to add additional fields to json, you need to add them in this class.

<?php
/**
 * @author Ravi Tamada
 * @link URL Tutorial link
 */

class Push{
    // push message title
    private $title;
    
    // push message payload
    private $data;
    
    // flag indicating background task on push received
    private $is_background;
    
    // flag to indicate the type of notification
    private $flag;
    
    function __construct() {
        
    }
    
    public function setTitle($title){
        $this->title = $title;
    }
    
    public function setData($data){
        $this->data = $data;
    }
    
    public function setIsBackground($is_background){
        $this->is_background = $is_background;
    }
    
    public function setFlag($flag){
        $this->flag = $flag;
    }
    
    public function getPush(){
        $res = array();
        $res['title'] = $this->title;
        $res['is_background'] = $this->is_background;
        $res['flag'] = $this->flag;
        $res['data'] = $this->data;
        
        return $res;
    }
}

10. At this stage, we have all the necessary functions ready. Let’s start preparing the REST API endpoints for the android app. Create a file named .htaccess inside v1 folder and add below rules.

RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]

11. Create index.php inside v1 folder. All the rest api requests will be handled by this file only.

<?php

error_reporting(-1);
ini_set('display_errors', 'On');

require_once '../include/db_handler.php';
require '.././libs/Slim/Slim.php';

\Slim\Slim::registerAutoloader();

$app = new \Slim\Slim();

// User login
$app->post('/user/login', function() use ($app) {
    // check for required params
    verifyRequiredParams(array('name', 'email'));

    // reading post params
    $name = $app->request->post('name');
    $email = $app->request->post('email');

    // validating email address
    validateEmail($email);

    $db = new DbHandler();
    $response = $db->createUser($name, $email);

    // echo json response
    echoRespnse(200, $response);
});


/* * *
 * Updating user
 *  we use this url to update user's gcm registration id
 */
$app->put('/user/:id', function($user_id) use ($app) {
    global $app;

    verifyRequiredParams(array('gcm_registration_id'));

    $gcm_registration_id = $app->request->put('gcm_registration_id');

    $db = new DbHandler();
    $response = $db->updateGcmID($user_id, $gcm_registration_id);

    echoRespnse(200, $response);
});

/* * *
 * fetching all chat rooms
 */
$app->get('/chat_rooms', function() {
    $response = array();
    $db = new DbHandler();

    // fetching all user tasks
    $result = $db->getAllChatrooms();

    $response["error"] = false;
    $response["chat_rooms"] = array();

    // pushing single chat room into array
    while ($chat_room = $result->fetch_assoc()) {
        $tmp = array();
        $tmp["chat_room_id"] = $chat_room["chat_room_id"];
        $tmp["name"] = $chat_room["name"];
        $tmp["created_at"] = $chat_room["created_at"];
        array_push($response["chat_rooms"], $tmp);
    }

    echoRespnse(200, $response);
});

/**
 * Messaging in a chat room
 * Will send push notification using Topic Messaging
 *  */
$app->post('/chat_rooms/:id/message', function($chat_room_id) {
    global $app;
    $db = new DbHandler();

    verifyRequiredParams(array('user_id', 'message'));

    $user_id = $app->request->post('user_id');
    $message = $app->request->post('message');

    $response = $db->addMessage($user_id, $chat_room_id, $message);

    if ($response['error'] == false) {
        require_once __DIR__ . '/../libs/gcm/gcm.php';
        require_once __DIR__ . '/../libs/gcm/push.php';
        $gcm = new GCM();
        $push = new Push();

        // get the user using userid
        $user = $db->getUser($user_id);

        $data = array();
        $data['user'] = $user;
        $data['message'] = $response['message'];
        $data['chat_room_id'] = $chat_room_id;

        $push->setTitle("Google Cloud Messaging");
        $push->setIsBackground(FALSE);
        $push->setFlag(PUSH_FLAG_CHATROOM);
        $push->setData($data);
        
        // echo json_encode($push->getPush());exit;

        // sending push message to a topic
        $gcm->sendToTopic('topic_' . $chat_room_id, $push->getPush());

        $response['user'] = $user;
        $response['error'] = false;
    }

    echoRespnse(200, $response);
});


/**
 * Sending push notification to a single user
 * We use user's gcm registration id to send the message
 * * */
$app->post('/users/:id/message', function($to_user_id) {
    global $app;
    $db = new DbHandler();

    verifyRequiredParams(array('message'));

    $from_user_id = $app->request->post('user_id');
    $message = $app->request->post('message');

    $response = $db->addMessage($from_user_id, $to_user_id, $message);

    if ($response['error'] == false) {
        require_once __DIR__ . '/../libs/gcm/gcm.php';
        require_once __DIR__ . '/../libs/gcm/push.php';
        $gcm = new GCM();
        $push = new Push();

        $user = $db->getUser($to_user_id);

        $data = array();
        $data['user'] = $user;
        $data['message'] = $response['message'];
        $data['image'] = '';

        $push->setTitle("Google Cloud Messaging");
        $push->setIsBackground(FALSE);
        $push->setFlag(PUSH_FLAG_USER);
        $push->setData($data);

        // sending push message to single user
        $gcm->send($user['gcm_registration_id'], $push->getPush());

        $response['user'] = $user;
        $response['error'] = false;
    }

    echoRespnse(200, $response);
});


/**
 * Sending push notification to multiple users
 * We use gcm registration ids to send notification message
 * At max you can send message to 1000 recipients
 * * */
$app->post('/users/message', function() use ($app) {

    $response = array();
    verifyRequiredParams(array('user_id', 'to', 'message'));

    require_once __DIR__ . '/../libs/gcm/gcm.php';
    require_once __DIR__ . '/../libs/gcm/push.php';

    $db = new DbHandler();

    $user_id = $app->request->post('user_id');
    $to_user_ids = array_filter(explode(',', $app->request->post('to')));
    $message = $app->request->post('message');

    $user = $db->getUser($user_id);
    $users = $db->getUsers($to_user_ids);

    $registration_ids = array();

    // preparing gcm registration ids array
    foreach ($users as $u) {
        array_push($registration_ids, $u['gcm_registration_id']);
    }

    // insert messages in db
    // send push to multiple users
    $gcm = new GCM();
    $push = new Push();

    // creating tmp message, skipping database insertion
    $msg = array();
    $msg['message'] = $message;
    $msg['message_id'] = '';
    $msg['chat_room_id'] = '';
    $msg['created_at'] = date('Y-m-d G:i:s');

    $data = array();
    $data['user'] = $user;
    $data['message'] = $msg;
    $data['image'] = '';

    $push->setTitle("Google Cloud Messaging");
    $push->setIsBackground(FALSE);
    $push->setFlag(PUSH_FLAG_USER);
    $push->setData($data);

    // sending push message to multiple users
    $gcm->sendMultiple($registration_ids, $push->getPush());

    $response['error'] = false;

    echoRespnse(200, $response);
});

$app->post('/users/send_to_all', function() use ($app) {

    $response = array();
    verifyRequiredParams(array('user_id', 'message'));

    require_once __DIR__ . '/../libs/gcm/gcm.php';
    require_once __DIR__ . '/../libs/gcm/push.php';

    $db = new DbHandler();

    $user_id = $app->request->post('user_id');
    $message = $app->request->post('message');

    require_once __DIR__ . '/../libs/gcm/gcm.php';
    require_once __DIR__ . '/../libs/gcm/push.php';
    $gcm = new GCM();
    $push = new Push();

    // get the user using userid
    $user = $db->getUser($user_id);
    
    // creating tmp message, skipping database insertion
    $msg = array();
    $msg['message'] = $message;
    $msg['message_id'] = '';
    $msg['chat_room_id'] = '';
    $msg['created_at'] = date('Y-m-d G:i:s');

    $data = array();
    $data['user'] = $user;
    $data['message'] = $msg;
    $data['image'] = 'https://www.androidhive.info/wp-content/uploads/2016/01/Air-1.png';

    $push->setTitle("Google Cloud Messaging");
    $push->setIsBackground(FALSE);
    $push->setFlag(PUSH_FLAG_USER);
    $push->setData($data);

    // sending message to topic `global`
    // On the device every user should subscribe to `global` topic
    $gcm->sendToTopic('global', $push->getPush());

    $response['user'] = $user;
    $response['error'] = false;

    echoRespnse(200, $response);
});

/**
 * Fetching single chat room including all the chat messages
 *  */
$app->get('/chat_rooms/:id', function($chat_room_id) {
    global $app;
    $db = new DbHandler();

    $result = $db->getChatRoom($chat_room_id);

    $response["error"] = false;
    $response["messages"] = array();
    $response['chat_room'] = array();

    $i = 0;
    // looping through result and preparing tasks array
    while ($chat_room = $result->fetch_assoc()) {
        // adding chat room node
        if ($i == 0) {
            $tmp = array();
            $tmp["chat_room_id"] = $chat_room["chat_room_id"];
            $tmp["name"] = $chat_room["name"];
            $tmp["created_at"] = $chat_room["chat_room_created_at"];
            $response['chat_room'] = $tmp;
        }

        if ($chat_room['user_id'] != NULL) {
            // message node
            $cmt = array();
            $cmt["message"] = $chat_room["message"];
            $cmt["message_id"] = $chat_room["message_id"];
            $cmt["created_at"] = $chat_room["created_at"];

            // user node
            $user = array();
            $user['user_id'] = $chat_room['user_id'];
            $user['username'] = $chat_room['username'];
            $cmt['user'] = $user;

            array_push($response["messages"], $cmt);
        }
    }

    echoRespnse(200, $response);
});

/**
 * Verifying required params posted or not
 */
function verifyRequiredParams($required_fields) {
    $error = false;
    $error_fields = "";
    $request_params = array();
    $request_params = $_REQUEST;
    // Handling PUT request params
    if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
        $app = \Slim\Slim::getInstance();
        parse_str($app->request()->getBody(), $request_params);
    }
    foreach ($required_fields as $field) {
        if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) {
            $error = true;
            $error_fields .= $field . ', ';
        }
    }

    if ($error) {
        // Required field(s) are missing or empty
        // echo error json and stop the app
        $response = array();
        $app = \Slim\Slim::getInstance();
        $response["error"] = true;
        $response["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty';
        echoRespnse(400, $response);
        $app->stop();
    }
}

/**
 * Validating email address
 */
function validateEmail($email) {
    $app = \Slim\Slim::getInstance();
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $response["error"] = true;
        $response["message"] = 'Email address is not valid';
        echoRespnse(400, $response);
        $app->stop();
    }
}

function IsNullOrEmptyString($str) {
    return (!isset($str) || trim($str) === '');
}

/**
 * Echoing json response to client
 * @param String $status_code Http response code
 * @param Int $response Json response
 */
function echoRespnse($status_code, $response) {
    $app = \Slim\Slim::getInstance();
    // Http response code
    $app->status($status_code);

    // setting response content type to json
    $app->contentType('application/json');

    echo json_encode($response);
}

$app->run();
?>

REST API Endpoints

The index.php inside v1 folder providers the below endpoints.

Base URL: http://localhost/gcm_chat/v1

Endpoint Params Method Description
/user/login name, email POST User login or registration
/user/:id gcm_registration_id PUT Updates user’s gcm registration id in database
/chat_rooms GET Fetches all chat rooms
/chat_rooms/:id replace :id with actual chat room id GET Fetches single chat room messages
/chat_rooms/:id/message replace :id with actual chat room id POST Posting a message in a chat room
/users/:id/message replace :id with actual user id POST Sending a message to user
/users/message user_id, to, message
`to` – param is user ids separated by comma (,)
POST Sending a message to multiple users
/users/send_to_all user_id, message POST Sending a message to all the users subscribed to `global` topic

6. Testing the REST API

Before starting the android project, make sure that the php project is running without any errors. Follow the below steps to test the API.

1. Enable apache mod_rewrite module (link)

2. Enable curl extension. This allows php to make http requests from the backend (link).

3. Install Postman Chrome REST API extension. You can use any other rest api clients too.

The below video takes you through testing the API using Postman.

7. Building the Admin Panel

I created very simple admin panel using PHP, HTML, CSS & jQuery. This admin panel might not be used in production stage, but gives you necessary functions to build a better one.

1. Create a file named demo.php in the root directory of gcm_chat. This class contains function for the admin panel.

<?php

/**
 * Class to handle all db operations
 * This class will have CRUD methods for database tables
 *
 * @author Ravi Tamada
 */
class Demo {

    private $conn;

    function __construct() {
        require_once dirname(__FILE__) . '/include/db_connect.php';
        // opening db connection
        $db = new DbConnect();
        $this->conn = $db->connect();
    }

    public function getAllChatRooms() {
        $stmt = $this->conn->prepare("SELECT * FROM chat_rooms");
        $stmt->execute();
        $tasks = $stmt->get_result();
        $stmt->close();
        return $tasks;
    }

    public function getAllUsers() {
        $stmt = $this->conn->prepare("SELECT * FROM users");
        $stmt->execute();
        $tasks = $stmt->get_result();
        $stmt->close();
        return $tasks;
    }

    public function getDemoUser() {
        $name = 'AndroidHive';
        $email = 'admin@androidhive.info';
        
        $stmt = $this->conn->prepare("SELECT user_id from users WHERE email = ?");
        $stmt->bind_param("s", $email);
        $stmt->execute();
        $stmt->store_result();
        $num_rows = $stmt->num_rows;
        if ($num_rows > 0) {
            $stmt->bind_result($user_id);
            $stmt->fetch();
            return $user_id;
        } else {
            $stmt = $this->conn->prepare("INSERT INTO users(name, email) values(?, ?)");
            $stmt->bind_param("ss", $name, $email);
            $result = $stmt->execute();
            $user_id = $stmt->insert_id;
            $stmt->close();
            return $user_id;
        }
    }
}
?>

2. Create a style sheet named style.css in the root directory.

/* 
    Created on : 22 Jan, 2016, 10:12:06 PM
    Author     : Ravi Tamada
*/

body{
    width: 100%;
    margin: 0;
    padding: 0;   
    font-family: 'Raleway', sans-serif;
}
.container_body{
    width: 1000px;
    margin: 0 auto;
}
.header{
    padding: 100px 0;
    text-align: center;
    color: #fff;
    background: -moz-radial-gradient(center, ellipse cover, rgba(227,71,73,1) 0%, rgba(186,27,31,1) 100%); /* ff3.6+ */
    background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgba(227,71,73,1)), color-stop(100%, rgba(186,27,31,1))); /* safari4+,chrome */
    background:-webkit-radial-gradient(center, ellipse cover, rgba(227,71,73,1) 0%, rgba(186,27,31,1) 100%); /* safari5.1+,chrome10+ */
    background: -o-radial-gradient(center, ellipse cover, rgba(227,71,73,1) 0%, rgba(186,27,31,1) 100%); /* opera 11.10+ */
    background: -ms-radial-gradient(center, ellipse cover, rgba(227,71,73,1) 0%, rgba(186,27,31,1) 100%); /* ie10+ */
    background:radial-gradient(ellipse at center, rgba(227,71,73,1) 0%, rgba(186,27,31,1) 100%); /* w3c */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e34749', endColorstr='#ba1b1f',GradientType=1 ); /* ie6-9 */
}
.header .logo{
    font-weight: bold;
    font-size: 30px;
    display: block;
    margin: 10px 0;
    letter-spacing: 3px;
}
.header h2{
    display: block;
    font-size: 50px;
    font-weight: 100;
    line-height: 10px;
}
.header h2.small{
    font-size: 25px;
    font-weight: 300;
    padding-top: 20px;
    letter-spacing: 1px;
}
.topics{
    text-align: center;
    padding-top: 50px;
}
.topics h2.heading{
    font-size: 30px;
    color: #666;
    font-weight: 400;
    display: block;
}
.box{
    width: 900px;
    margin: 40px auto;
    border: 1px solid #dedede;
    background: #f2f4f8;
    position: relative;
}
.box .usr_container,
.box .msg_container{
    float: left;
    height: 600px;
    overflow-x: hidden;
    overflow-y: auto;
}
.box .usr_container{
    width: 350px;
    border-right: 1px solid #dedede;
    background: #fff;
}
.box .msg_container{
    width: 548px;
    position: relative;
}
.box ul{
    margin: 0;
    padding: 0;
}
.box ul li{
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: left;
    cursor: pointer;
}

.box .usr_container ul li{
    padding: 20px 10px;
    background: #fff;
    border-bottom: 1px solid #dedede;
}
.box .usr_container ul li label{
    display: block;
    width: 100%;
    font-family: arial;
    font-weight: 400;
    color: #333;
    font-size: 18px;
    margin-bottom: 5px;
}
.box .usr_container ul li label:hover{
    cursor: pointer;
}
.box .usr_container ul li span{
    color: #777;
    font-family: arial;
    font-size: 14px;
    font-style: italic;
}
.box .usr_container ul li.selected{
    background: #f2f4f8;
}
.box .usr_container ul li.selected label{
    color: #e34749;
}
.box .usr_container ul li.selected span{
    color: #000;
}
.box .usr_container ul li:hover{
    background: #dedede;
    cursor: pointer;
}
.box .msg_container ul{
    padding: 10px 0;
    margin-bottom: 75px;
}
.box .msg_container li{
    padding: 10px 0;
}
.box .msg_container li.others{
    cursor: auto;
    text-align: left;
    padding-left: 20px;
}
.box .msg_container li.self{
    text-align: right;
    cursor: auto;
    padding-right: 20px;
}
.box .msg_container li.self label{
    float: right;
}
.box .msg_container li .message{
    background: #fff;
    border-radius: 3px;
    padding: 15px;
    max-width: 400px;
    font-size: 15px;
    font-family: arial;
    float: left;
    line-height: 20px;
    margin: 5px 0 10px 0;
}
.box .msg_container li label{
    float: left;
    display: block;
    width: 100%;
    font-size: 12px;
    color: #777;
    font-family: arial;
}
.box .msg_container li.others .message{

}
.box .msg_container li.self .message{
    background: #dee2ef;
    float: right;
    display: inline-block;
}
.clear{
    clear:both;
}
.send_container{
    border-top: 1px solid #dedede;
    background: #f7f9fd;
    position: absolute;
    bottom: 0;
    height:75px;
    right: 0;
}
.send_container textarea{
    background: #f7f9fd;
    height: 30px;
    width: 550px;
    font-size: 15px;
    text-align: left;
    padding: 20px;
    border: none;
    resize: none;
    outline: none;
}
.send_container input[type="button"]{
    position: absolute;
    top: 20px;
    right: 20px;
    padding: 10px;
    background: #e34749;
    outline: none;
    border: none;
    cursor: pointer;
    color: #fff;
    font-weight: bold;
    font-size: 15px;
}
.btn_send{
    padding: 10px;
    background: #e34749;
    outline: none;
    border: none;
    cursor: pointer;
    color: #fff;
    font-weight: bold;
    font-size: 15px;
}
.box .msg_container li label.name{
    display: block;
}
div.container{
    width: 900px;
    margin: 0 auto;
}
select.select_single{
    padding: 10px;
    font-size: 16px;
    width: 400px;
}
select.select_single option{
    font-size: 19px;
}
select.select_multiple{
    font-size: 15px;
    width: 400px;
    height: 200px;
}
select.select_multiple option{
    padding: 5px;
}
textarea.textarea_msg{
    width: 400px;
    height: 120px;
    resize: none;
    margin:20px auto;
    padding: 15px;
    background: #f7f9fd;
    font-size: 15px;
}
.loader{
    display: none;
}
pre{
    width: 800px;
    text-align: left !important;
    font-size: 16px;
    font-family: monospace;
    margin: 0 auto;
    line-height: 20px;
}
.separator{
    width: 100%;
    height: 1px;
    background: #cdcdcd;
    margin: 50px 0;
}

3. Paste the loader.gif image in the same directory.

4. Create index.php in the root directory. Here I have written necessary php, html and jQuery code to build the admin UI.

<?php
error_reporting(-1);
ini_set('display_errors', 'On');
?>

<?php
require_once __DIR__ . '/demo.php';
$demo = new Demo();
$admin_id = $demo->getDemoUser();
?>

<html>
    <head>
        <title>Google Cloud Messaging 3.0 | AndroidHive</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href='https://fonts.googleapis.com/css?family=Raleway:400,800,100' rel='stylesheet' type='text/css'>
        <link href='style.css' rel='stylesheet' type='text/css'>
        <link href='https://api.androidhive.info/gcm/styles/default.css' rel='stylesheet' type='text/css'>
        <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
        <script type="text/javascript">
            var user_id = '<?= $admin_id ?>';
            $(document).ready(function () {

                getChatroomMessages($('#topics li:first').attr('id'));


                $('ul#topics li').on('click', function () {
                    $('ul#topics li').removeClass('selected');
                    $(this).addClass('selected');
                    getChatroomMessages($(this).prop('id'))
                });

                function getChatroomMessages(id) {
                    $.getJSON("v1/chat_rooms/" + id, function (data) {
                        var li = '';
                        $.each(data.messages, function (i, message) {
                            li += '<li class="others"><label class="name">' + message.user.username + '</label><div class="message">' + message.message + '</div><div class="clear"></div></li>';
                        });
                        $('ul#topic_messages').html(li);
                        if (data.messages.length > 0) {
                            scrollToBottom('msg_container_topic');
                        }
                    }).done(function () {

                    }).fail(function () {
                        alert('Sorry! Unable to fetch topic messages');
                    }).always(function () {

                    });

                    // attaching the chatroom id to send button
                    $('#send_to_topic').attr('chat_room', id);
                }

                $('#send_to_topic').on('click', function () {
                    var msg = $('#send_to_topic_message').val();
                    if (msg.trim().length === 0) {
                        alert('Enter a message');
                        return;
                    }

                    $('#send_to_topic_message').val('');
                    $('#loader_topic').show();

                    $.post("v1/chat_rooms/" + $(this).attr('chat_room') + '/message',
                            {user_id: user_id, message: msg},
                    function (data) {
                        if (data.error === false) {
                            var li = '<li class="self" tabindex="1"><label class="name">' + data.user.name + '</label><div class="message">' + data.message.message + '</div><div class="clear"></div></li>';
                            $('ul#topic_messages').append(li);
                            scrollToBottom('msg_container_topic');
                        } else {
                            alert('Sorry! Unable to send message');
                        }
                    }).done(function () {

                    }).fail(function () {
                        alert('Sorry! Unable to send message');
                    }).always(function () {
                        $('#loader_topic').hide();
                    });
                });

                $('input#send_to_single_user').on('click', function () {
                    var msg = $('#send_to_single').val();
                    var to = $('.select_single').val();
                    if (msg.trim().length === 0) {
                        alert('Enter a message');
                        return;
                    }

                    $('#send_to_single').val('');
                    $('#loader_single').show();

                    $.post("v1/users/" + to + '/message',
                            {user_id: user_id, message: msg},
                    function (data) {
                        if (data.error === false) {
                            $('#loader_single').hide();
                            alert('Push notification sent successfully! You should see a Toast message on device.');
                        } else {
                            alert('Sorry! Unable to post message');
                        }
                    }).done(function () {

                    }).fail(function () {
                        alert('Sorry! Unable to send message');
                    }).always(function () {
                        $('#loader_single').hide();
                    });
                });

                $('input#send_to_multiple_users').on('click', function () {
                    var msg = $('#send_to_multiple').val();
                    var to = $('.select_multiple').val();

                    if (to === null) {
                        alert("Please select the users!");
                        return;
                    }

                    if (msg.trim().length === 0) {
                        alert('Enter a message');
                        return;
                    }

                    $('#send_to_multiple').val('');
                    $('#loader_multiple').show();

                    var selMulti = $.map($(".select_multiple option:selected"), function (el, i) {
                        return $(el).val();
                    });

                    to = selMulti.join(",");

                    $.post("v1/users/message",
                            {user_id: user_id, to: to, message: msg},
                    function (data) {
                        if (data.error === false) {
                            $('#loader_multiple').hide();
                            alert('Push notification sent successfully to multiple users');
                        } else {
                            alert('Sorry! Unable to send message');
                        }
                    }).done(function () {

                    }).fail(function () {
                        alert('Sorry! Unable to send message');
                    }).always(function () {
                        $('#loader_multiple').hide();
                    });
                });

                $('input#send_to_multiple_users_with_image').on('click', function () {

                    var msg = $('#send_to_multiple_with_image').val();
                    if (msg.trim().length === 0) {
                        alert('Enter a message');
                        return;
                    }

                    $('#send_to_multiple_with_image').val('');
                    $('#loader_multiple_with_image').show();

                    $.post("v1/users/send_to_all",
                            {user_id: user_id, message: msg},
                    function (data) {
                        if (data.error === false) {
                            $('#loader_multiple_with_image').hide();
                            alert('Push notification sent successfully to multiple users');
                        } else {
                            alert('Sorry! Unable to send message');
                        }
                    }).done(function () {

                    }).fail(function () {
                        alert('Sorry! Unable to send message');
                    }).always(function () {
                        $('#loader_topic_with_image').hide();
                    });
                });

                function scrollToBottom(cls) {
                    $('.' + cls).scrollTop($('.' + cls + ' ul li').last().position().top + $('.' + cls + ' ul li').last().height());
                }
            });
        </script>
    </head>
    <body>
        <div class="header">
            <label class="logo">ANDROIDHIVE</label>
            <h2>Google Cloud Messaging</h2>
            <h2 class="small">Sending push notifications using Android, PHP & MySQL</h2>
        </div>
        <div class="container_body">
            <div class="topics">
                <h2 class="heading">Download & Install the GCM apk</h2>
                Download & Install the Google Cloud Messaging <a href="#">apk</a> before trying the demos. <br/><br/>Once installed, refresh this page 
                to see your name, email in the recipients list.
            </div>

            <div class="topics">
                <div class="separator"></div>
                <h2 class="heading">Sending message to a `topic`</h2>
                Select any of the topics below and send a message.<br/><br/>
                <div class="box">
                    <div class="usr_container">
                        <ul id="topics">
                            <?php
                            $chatrooms = $demo->getAllChatRooms();
                            foreach ($chatrooms as $key => $chatroom) {
                                $cls = $key == 0 ? 'selected' : '';
                                ?>
                                <li id="<?= $chatroom['chat_room_id'] ?>" class="<?= $cls ?>">
                                    <label><?= $chatroom['name'] ?></label>
                                    <span>topic_<?= $chatroom['chat_room_id'] ?></span>
                                </li>
                                <?php
                            }
                            ?>
                        </ul>
                    </div>
                    <div class="msg_container msg_container_topic">
                        <ul id="topic_messages"></ul>
                    </div>
                    <div class="send_container">
                        <textarea placeholder="Type a message here" id="send_to_topic_message"></textarea>
                        <input id="send_to_topic" type="button" value="Send to Topic"/>
                        <img src="loader.gif" id="loader_topic" class="loader"/>
                    </div>
                    <div class="clear"></div>
                </div>
                <br/>
                <div class="separator"></div>
                <h2 class="heading">Sending message to `Single User`</h2>
                Select your name from the below recipients and send a message<br/><br/>

                <div class="container">
                    <select class="select_single">
                        <?php
                        $users = $demo->getAllUsers();
                        foreach ($users as $key => $user) {
                            ?>
                            <option value="<?= $user['user_id'] ?>"><?= $user['name'] ?> (<?= $user['email'] ?>)</option>
                            <?php
                        }
                        ?>
                    </select><br/>
                    <textarea id="send_to_single" class="textarea_msg" placeholder="Type a message"></textarea><br/>
                    <input id="send_to_single_user" type="button" value="Send to single user" class="btn_send"/>
                    <img src="loader.gif" id="loader_single" class="loader"/>
                </div>
                <br/>
                <div class="separator"></div>
                <h2 class="heading">Sending message to `Multiple Users`</h2>
                Select multiple recipients and send a message. You can use ctrl or shift to select multiple users<br/><br/><br/>

                <div class="container">
                    <select multiple class="select_multiple">
                        <?php
                        foreach ($users as $key => $user) {
                            ?>
                            <option value="<?= $user['user_id'] ?>"><?= $user['name'] ?> (<?= $user['email'] ?>)</option>
                            <?php
                        }
                        ?>
                    </select>
                    <br/>
                    <textarea id="send_to_multiple" class="textarea_msg" placeholder="Type a message"></textarea><br/>
                    <input id="send_to_multiple_users" type="button" value="Send to multiple users" class="btn_send"/>
                    <img src="loader.gif" id="loader_multiple" class="loader"/>
                </div>

                <br/>
                <div class="separator"></div>
                <h2 class="heading">Sending push notification with an `Image`</h2>
                A message with an image attachment will be sent to every user. You have to minimize or close the app in order to see
                it in action.<br/><br/>

                <div class="container">
                    <textarea id="send_to_multiple_with_image" class="textarea_msg" placeholder="Type a message"></textarea><br/>
                    <input id="send_to_multiple_users_with_image" type="button" value="Send with image" class="btn_send"/>
                    <img src="loader.gif" id="loader_multiple_with_image" class="loader"/>
                </div>
            </div>
            <br/><br/>
            <br/><br/>
            <br/><br/>
        </div>
    </body>
</html>

5. Finally access the admin panel by going to http://localhost/gcm_chat/ (If your apache is running under a port, add the port number to localhost)

You should able to see the below admin panel which provides options to send the messages to devices from admin panel. Here the Live Demo of the admin app.

android-gcm-chat-app-admin-panel

With this we have completed 1s part of the article, but before moving to 2nd Part, quickly go through below code snippets which are very useful if you want to extend the server app functionality.

7. Quick Code Snippets

Sending Push To Single User

        require_once __DIR__ . '/../libs/gcm/gcm.php';
        require_once __DIR__ . '/../libs/gcm/push.php';
        $gcm = new GCM();
        $push = new Push();

        $data = array();
        // user node
        $data['user'] = $user;
        // message node
        $data['message'] = $response['message'];
        $data['image'] = '';

        $push->setTitle("Google Cloud Messaging");
        $push->setIsBackground(FALSE);
        $push->setFlag(PUSH_FLAG_USER);
        $push->setData($data);

        // Pass the receiver gcm registration token
        $gcm_registration_id = 'fnFAQ_BA7pY:APA91bFOwrCw9LHhJKatfvMx-2XA7-NdUMUMF5c9RS0....';

        // sending push message to single user
        $gcm->send($user['gcm_registration_id'], $push->getPush());

Sending Push To Multiple Users

    require_once __DIR__ . '/../libs/gcm/gcm.php';
    require_once __DIR__ . '/../libs/gcm/push.php';

    $gcm = new GCM();
    $push = new Push();

    $msg = array();
    $msg['message'] = $message;
    $msg['message_id'] = '';
    $msg['chat_room_id'] = '';
    $msg['created_at'] = date('Y-m-d G:i:s');

    $data = array();
    $data['user'] = $user;
    $data['message'] = $msg;
    $data['image'] = '';

    $push->setTitle("Google Cloud Messaging");
    $push->setIsBackground(FALSE);
    $push->setFlag(PUSH_FLAG_USER);
    $push->setData($data);

    // Keep all the recipients gcm tokens in an array 
    $registration_ids = array('fnFAQ_BA7pY:APA91bFOwrCw9LHhJKatfvMx-2XA7-NdUMUMF5c9RS0....', 'fnFAQ_BA7pY:APA91bFOwrCw9LHhJKatfvMx-2XA7-NdUMUMF5c9RS0....');

    // sending push message to multiple users
    $gcm->sendMultiple($registration_ids, $push->getPush());

Sending Push To a Topic

        require_once __DIR__ . '/../libs/gcm/gcm.php';
        require_once __DIR__ . '/../libs/gcm/push.php';

        $gcm = new GCM();
        $push = new Push();

        $data = array();
        $data['user'] = $user;
        $data['message'] = $response['message'];
        $data['chat_room_id'] = $chat_room_id;

        $push->setTitle("Google Cloud Messaging");
        $push->setIsBackground(FALSE);
        $push->setFlag(PUSH_FLAG_CHATROOM);
        $push->setData($data);

        // the topic you want to send notification
        $topic = 'your_topic_name';

        // sending push message to a topic
        $gcm->sendToTopic($topic, $push->getPush());

Sending Push with an Image

        require_once __DIR__ . '/../libs/gcm/gcm.php';
        require_once __DIR__ . '/../libs/gcm/push.php';

        $gcm = new GCM();
        $push = new Push();

        // keep the notification image url here
        $image = 'https://api.androidhive.info/gcm/panda.jpg';

        $data = array();
        $data['user'] = $user;
        $data['message'] = $response['message'];
        $data['image'] = $image;

        $push->setTitle("Google Cloud Messaging");
        $push->setIsBackground(FALSE);
        $push->setFlag(PUSH_FLAG_USER);
        $push->setData($data);

        $gcm_registration_id = 'fnFAQ_BA7pY:APA91bFOwrCw9LHhJKatfvMx-2XA7-NdUMUMF5c9RS0....';

        // sending push message to single user
        $gcm->send($user['gcm_registration_id'], $push->getPush());

By far we have successfully built the proper REST API client and a simple admin panel. Now let’s start building the android app in 2nd Part. If you are facing any issue in this part, please comment in below discussions.

Subscribe
Notify of
guest
609 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
varun
varun
4 years ago

Thank you for new tutorial bro..can you post a tutorial with beacons

Ravi Tamada
4 years ago
Reply to  varun

I guess I need to buy a Beacon right?

varun
varun
4 years ago
Reply to  Ravi Tamada

yes..any app using beacons..how to detect beacon and etc..

Anupam Anand
Anupam Anand
4 years ago

by impleming first part this is what i am getting can you please check what is wrong in it.
http://booksasap.in/gcm_chat ca

Ravi Tamada
4 years ago
Reply to  Anupam Anand

Install mysqlnd drivers on your server.

Anupam Anand
Anupam Anand
4 years ago
Reply to  Ravi Tamada

How to do that
?

Ravi Tamada
4 years ago
Reply to  Anupam Anand

Its not possible on most of the shared hosting servers. But if you have VPS, you can install on your own.

http://stackoverflow.com/questions/23158943/install-both-mysql-and-mysqlnd-on-ubuntu-12-04

http://stackoverflow.com/questions/13159518/how-to-enable-mysqlnd-for-php

Gon Her
Gon Her
4 years ago
Reply to  Anupam Anand

Hi. He could solve the problem? I have the same error.

Ravi Tamada
4 years ago
Reply to  Gon Her

Your database credentials are wrong. Keep correct username, password, database name.

Oussama
Oussama
4 years ago

hello
how can we send as push msg with GCM for free?

Ravi Tamada
4 years ago
Reply to  Oussama

Hi Oussama, GCM is already free.

Rishika Kapur
Rishika Kapur
4 years ago

Hi Ravi!

I don’t want to use local development environment (MAMP) instead I want to use Hostgator. Should I follow the exact steps or there are something different need to be done?

Ravi Tamada
4 years ago
Reply to  Rishika Kapur

Yeah you can. But make sure that hostgator is supporting musqlnd. Just download the code, upload it to hostgator and verify.

Hamdi wanis
Hamdi wanis
4 years ago
Reply to  Ravi Tamada

what if it does not ?

Lucky Bhumkar
Lucky Bhumkar
4 years ago

Master Piece.. great you have illustrated it in it’s easiest level..!

Ravi Tamada
4 years ago
Reply to  Lucky Bhumkar

Yeah I spent lot time writing it.

Sohel Rana
4 years ago

nice tutorial…

박준혁
박준혁
4 years ago

Oh my god….This Tutorial is great!I almost certainly love u!

Ravi Tamada
4 years ago
Reply to  박준혁

Thank You.

daniel dizzy
daniel dizzy
4 years ago

Thansk again Ravi, your tutorials are very self explanatory. Am always greatful.

Ravi Tamada
4 years ago
Reply to  daniel dizzy

You are welcome:)

Justin Smith
Justin Smith
4 years ago

thanks for your great tutorials

Rege
Rege
4 years ago

Hello Ravi,

I setup and install api. Thank you the tutorial.
But I have one problem. If I write the messages I don’t see the phone real time… If I open the room i can see after loading the room. What do I do wrong? Thank you your answers.

Ravi Tamada
4 years ago
Reply to  Rege

After login check whether gcm registration token is printing in LogCat or not.

Nitesh
Nitesh
4 years ago

I did everything as explained but i am getting error 404 Page Not Found.. I have enabled apache rewrite mod and curl extension. index.php is working fine but when i am adding localhost/gcm_chat/v1 its show page not found. I am using xampp.. Please guide.. Thanks

Ravi Tamada
4 years ago
Reply to  Nitesh

localhost/gcm_chat/v1 always gives 404. You need to access the final endpoint with the correct http method

localhost/gcm_chat/v1/user/login with POST method.

Ricky
Ricky
4 years ago
Reply to  Ravi Tamada

replace ‘localhost’ to your IPAdress. For example
public static final String BASE_URL = “http://192.168.82.10/gcm_chat/v1”;

Rinku Meena
Rinku Meena
4 years ago
Reply to  Nitesh

use url /gcm_chat/v1/index.php/user/login and it will work

Thong Le
Thong Le
4 years ago

Hi Ravi. tks for awesome tut. But I have an error: when I test rest api by postman , I input name and email, the server always respone :{
“error”: true,
“message”: “Oops! An error occurred while registereing”
}

Radovan Heldák
Radovan Heldák
4 years ago
Reply to  Thong Le

I have the same problem 🙁

Ravi Tamada
4 years ago

Make sure you have created the mysql tables correctly and gave the correct database credentials in config file.

Thong Le
Thong Le
4 years ago
Reply to  Ravi Tamada

thank for your reply, I fixed it by coppy all code MySQL from folder db (downloaded) without copy code from web.

Ravi Tamada
4 years ago
Reply to  Thong Le

Okay. Let me check the website SQL code again. Thanks.

M
M
4 years ago
Reply to  Ravi Tamada

SQL codes from this page does not include adding auto_increment in user_id.
That’s why people can not make a new user because there is always 0 in user_id (primary key, unique as default).

Daniele
Daniele
4 years ago
Reply to  M

so how can we fix this?

Rishika Kapur
Rishika Kapur
4 years ago
Reply to  Thong Le

I am getting the same error. Can you explain, how did you fix it?

Rony Vidaur
Rony Vidaur
4 years ago
Reply to  Thong Le

I have still the same issue, even though I’ve try the solution provided here 🙁 any ideas?

Yaqoub Alsaadi
Yaqoub Alsaadi
4 years ago

hi Ravi
i get error
Volley error:null
i use locall sever(wamp)

siddhant jain
siddhant jain
4 years ago

hello…. how can i delete the chat msgs ..like we do in whatsapp…. & to include touch & select feature for msgs for forwarding it
& how to change the notification ringtone

sankalp bhambri
sankalp bhambri
4 years ago

Awesome tutorial. Working perfect 🙂

Ravi Tamada
4 years ago

Cheers!

Jaija
Jaija
4 years ago

Hi Ravi
I use http: //localhost/gcm_chat/push_test.php
when pressed send push notification messages are then sorry! unable to send message.

WaWaToR
WaWaToR
4 years ago

I am getting an error please help. Thanks

Fatal error: Call to a member function bind_param() on a non-object in /home/wawawebfep/www/gcm_chat/demo.php on line 42

Thandy
Thandy
4 years ago

Hi!! Thanks a lot for this tut!!

i am getting this erro:
~
Type: ErrorException

Code: 8

Message: Use of undefined constant PUSH_FLAG_CHATROOM – assumed ‘PUSH_FLAG_CHATROOM’

File: C:xampphtdocslocalhosthivegcm_chatv1index.php

Line: 106

Trace
#0 C:xampphtdocslocalhosthivegcm_chatv1index.php(106): SlimSlim::handleErrors(8, ‘Use of undefine…’, ‘C:xampphtdocs…’, 106, Array)
#1 [internal function]: {closure}(‘2’)
#2 C:xampphtdocslocalhosthivegcm_chatlibsSlimRoute.php(436): call_user_func_array(Object(Closure), Array)
#3 C:xampphtdocslocalhosthivegcm_chatlibsSlimSlim.php(1307): SlimRoute->dispatch()
#4 C:xampphtdocslocalhosthivegcm_chatlibsSlimMiddlewareFlash.php(85): SlimSlim->call()
#5 C:xampphtdocslocalhosthivegcm_chatlibsSlimMiddlewareMethodOverride.php(92): SlimMiddlewareFlash->call()
#6 C:xampphtdocslocalhosthivegcm_chatlibsSlimMiddlewarePrettyExceptions.php(67): SlimMiddlewareMethodOverride->call()
#7 C:xampphtdocslocalhosthivegcm_chatlibsSlimSlim.php(1254): SlimMiddlewarePrettyExceptions->call()
#8 C:xampphtdocslocalhosthivegcm_chatv1index.php(453): SlimSlim->run()
#9 {main}

Thandy
Thandy
4 years ago
Reply to  Thandy

I just solve… it was my mistake…

Thankssss

Ravi Tamada
4 years ago
Reply to  Thandy

OK

Khalid S.
Khalid S.
4 years ago

Hi Ravi, this tutorial is incredible. Thank you for your effort in writing it!

I was testing my REST API with Postman like in your video and everything works fine except for the PUT request.

I made sure to type in the parameter name very carefully “gcm_registration_id” but it refuses to work and I keep getting this message:

“error”: true,
“message”: “Required field(s) gcm_registration_id is missing or empty”

Do you know why this might be happening?

Ravi Tamada
4 years ago
Reply to  Khalid S.

Yeah, in Postman for PUT request choose x-www-form-urlencoded instead of form-data (see there is a radio button)

Khalid S.
Khalid S.
4 years ago
Reply to  Ravi Tamada

You are THE MAN! Thank you 🙂

Ravi Tamada
4 years ago
Reply to  Khalid S.

You are welcome 🙂

Navas AR
Navas AR
4 years ago

Hi ravi I have an error
Fatal error: Call to undefined method mysqli_stmt::get_result() in /localhost/www/gcm_chat/include/db_handler.php on line 164
json parsing error: <br of type java.lang.String cannot be converted to JSONObject

noah
noah
4 years ago
Reply to  Navas AR

seconded.

Noah
Noah
4 years ago
Reply to  noah

I fixed this by installing mysqlnd:

sudo apt-get install php5-mysqlnd
sudo service apache2 restart

Navas AR
Navas AR
4 years ago
Reply to  Noah

how to install it?

Mahesh
Mahesh
4 years ago

Hi Ravi, How can I get the gcm_registration_id I am new to Android can you please Elobarate

Ravi Tamada
4 years ago
Reply to  Mahesh

Check the part 2 of the article. You can see that I logged the gcm token in Main Activity.

Mahesh D
Mahesh D
4 years ago
Reply to  Mahesh

Thanks Ravi,
Okay where I can place Project Number (or) sender Id in this..

Ravi Tamada
4 years ago
Reply to  Mahesh D

We don’t use project number or sender id anymore like we did for older GCM. Instead we add google-services.json file where all these things will be configured. Check part 2 of this article.

Mahesh D
Mahesh D
4 years ago
Reply to  Ravi Tamada

Thanks,

Now I got voelly error
Log cat is

params: {email=mymailid@gmail.com, name=Mahesh}
02-21 12:15:24.497 19582-19963/info.androidhive.gcm E/Volley﹕ [162] BasicNetwork.performRequest: Unexpected response code 500 for http://192.168.1.3/cloud_chat/v1/user/login
02-21 12:15:24.513 19582-19582/info.androidhive.gcm E/LoginActivity﹕ Volley error: null, code: com.android.volley.NetworkResponse@4111964
02-21 12:15:24.667 19582-19611/info.androidhive.gcm W/EGL_emulation﹕ eglSurfaceAttrib not implemented

Can you please how can I login into app

Mahesh D
Mahesh D
4 years ago
Reply to  Mahesh D

public void addToRequestQueue(Request req) {

req.setTag(TAG);

getRequestQueue().add(req);

} and I debug the param req = I

[ ] http://192.168.1.3/cloud_chat/v1/user/login 0x355f917 NORMAL null… What I can get instead of 0x355f917

Ibrahim Samad
Ibrahim Samad
4 years ago

Thanks for the long awaited tutorial.
I want to implement this in a web app not an android app. Pls what will be the next step after this first part of the tutorial, Since I probably don’t need the second and third part.

Pankaj Lagad
Pankaj Lagad
4 years ago

Hi Ravi,
When I clicked on login button I got the following errors,
What will be the reason???

02-17 01:16:32.970 12507-12507/info.androidhive.googlecloudmessagingexample E/SpannableStringBuilder: SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
02-17 01:16:32.970 12507-12507/info.androidhive.googlecloudmessagingexample E/SpannableStringBuilder: SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
02-17 01:16:47.441 12507-12821/info.androidhive.googlecloudmessagingexample E/LoginActivity: params: {email=lagadpankaj@gmail.com, name=Pankaj Lagad}
02-17 01:16:47.480 12507-12821/info.androidhive.googlecloudmessagingexample E/Volley: [1260] BasicNetwork.performRequest: Unexpected response code 403 for http://192.168.42.125:80/gcm_chat/v1/user/login
02-17 01:16:47.481 12507-12821/info.androidhive.googlecloudmessagingexample E/LoginActivity: params: {email=lagadpankaj@gmail.com, name=Pankaj Lagad}
02-17 01:16:47.495 12507-12821/info.androidhive.googlecloudmessagingexample E/Volley: [1260] BasicNetwork.performRequest: Unexpected response code 403 for http://192.168.42.125:80/gcm_chat/v1/user/login
02-17 01:16:47.502 12507-12507/info.androidhive.googlecloudmessagingexample E/LoginActivity: Volley error: null, code: com.android.volley.NetworkResponse@42d8b0f0

noah
noah
4 years ago

Hey Ravi,

Your demo at http://demo.androidhive.info/gcm_chat/ has been hacked. Displays porn now… Might want to fix that. This is why we can’t have nice things.

gw
gw
4 years ago

I’m hitting a 404 and am out of ideas. I have ensured that mod_rewrite and curl are enabled. My site can be hit at gcm_chat/ (although i get “Sorry! Unable to fetch topic messages”). When I use postman to GET http://ec2-XX-XXX-XXX-XXX.compute-1.amazonaws.com/gcm_chat/v1/chat_rooms I get

404 Not Found

Not Found
The requested URL /gcm_chat/v1/chat_rooms was not found on this server.

Apache/2.4.7 (Ubuntu) Server at ec2-XX-XXX-XXX-XXX.compute-1.amazonaws.com Port 80

I have tried changing permissions of my virtual host… My full dir to the project is /var/www/html/gcm_chat. I am using a default install of apache2. I haven’t been able to observe any php errors.

Help?

Rinku Meena
Rinku Meena
4 years ago
Reply to  gw

use url /gcm_chat/v1/index.php/user/login and it will work

Hamdi wanis
Hamdi wanis
4 years ago

hey ravi i used hostinger to host the server side and i made sure it has mysqlnd enabled but i still get Call to undefined method mysqli_stmt::get_result() ? any ideas?

Pankaj Lagad
Pankaj Lagad
4 years ago

Hi ravi I got the following errors,

//when sent the message from our device to chat room(Material Design)

02-20 14:02:04.216 26053-26053/? E/ChatRoomActivity: endpoint: http://192.168.42.102/gcm_chat/v1/chat_rooms/1/message
02-20 14:02:04.261 682-682/? E/RemoteViews: ANR Warning,RemoteViews can only be used once ,if not ,it may cause ANR in hosts such as Laucher,SystemUI. keys for search
02-20 14:02:04.264 26053-26287/? E/ChatRoomActivity: Params: {message=haha, user_id=20}
02-20 14:02:04.266 682-682/? E/RemoteViews: ANR Warning,RemoteViews can only be used once ,if not ,it may cause ANR in hosts such as Laucher,SystemUI. keys for search
02-20 14:02:04.333 26053-26053/? E/ChatRoomActivity: response: {“error”:true,”message”:”Failed send message”}

whats going wrong… I also can’t sent the massage to single user

reply soon..

Alexandre Queiroz
Alexandre Queiroz
4 years ago

thank you, you does a great job

Ravi Tamada
4 years ago

You are welcome. Follow the other two parts too.

Yaqoub Alsaadi
Yaqoub Alsaadi
4 years ago

brother Ravi Tamada

thanks aloot
i need your help to upload php files to 00webhost….

waiting you brother

Ravi Tamada
4 years ago
Reply to  Yaqoub Alsaadi

Hi Yaqoub

This app won’t work on 000webhost because of the limitations. 000webhost won’t support mysqlnd.

Yaqoub Alsaadi
Yaqoub Alsaadi
4 years ago
Reply to  Ravi Tamada

thank you Ravi
is there any way to use web server ?

Ravi Tamada
4 years ago
Reply to  Yaqoub Alsaadi

Please try to host the services on to 000webhost. Once done you can see the errors in the log when accessing the urls. Then I can tell you what to do exactly.

Yaqoub Alsaadi
Yaqoub Alsaadi
4 years ago
Reply to  Ravi Tamada

now i face this :-
Fatal error: Call to undefined method mysqli_stmt::get_result() in /home/a1657826/public_html/gcm3/demo.php on line 24

Ravi Tamada
4 years ago
Reply to  Yaqoub Alsaadi

Your webhosting is not supporting mysqlnd. You have to convert all the mysqli statements to PDO.

Yaqoub Alsaadi
Yaqoub Alsaadi
4 years ago
Reply to  Ravi Tamada

thanks Ravi
I have no idea in php…

Alankrita
Alankrita
4 years ago
Reply to  Yaqoub Alsaadi

Instead of get_result(), you could use this method :

function get_result( $Statement ) {
$RESULT = array();
$Statement->store_result();
for ( $i = 0; $i num_rows; $i++ ) {
$Metadata = $Statement->result_metadata();
$PARAMS = array();
while ( $Field = $Metadata->fetch_field() ) {
$PARAMS[] = &$RESULT[ $i ][ $Field->name ];
}
call_user_func_array( array( $Statement, ‘bind_result’ ), $PARAMS );
$Statement->fetch();
}
return $RESULT;
}

And to process the result, instead of $result->fetch_assoc()
use – array_shift( $RESULT )

Yaqoub Alsaadi
Yaqoub Alsaadi
4 years ago
Reply to  Alankrita

thanks Alankrita
i did what you said but i get this

Warning: Invalid argument supplied for foreach() in /home/a1657826/public_html/gcm3/index.php on line 212

could i contact by your email??

Alankrita
Alankrita
4 years ago
Reply to  Yaqoub Alsaadi

You have to edit three files : demo.php, v1/index.php and db_handler.php

In demo.php :

public function getAllChatRooms() {
$stmt = $this->conn->prepare(“SELECT * FROM chat_rooms”);
$stmt->execute();
//$stmt->store_result();
$RESULT = get_result( $stmt );
$stmt->close();
return $RESULT;
}

public function getAllUsers() {
$stmt = $this->conn->prepare(“SELECT * FROM users”);
$stmt->execute();
$RESULT = get_result( $stmt );
//$tasks = $stmt->fetch();
$stmt->close();
return $RESULT;
}

In db_handler.php

// fetching all chat rooms
public function getAllChatrooms() {
$stmt = $this->conn->prepare(“SELECT * FROM chat_rooms”);
$stmt->execute();
// $tasks = $stmt->get_result();
$tasks = get_result( $stmt );

$stmt->close();
return $tasks;
}

// fetching single chat room by id
function getChatRoom($chat_room_id) {
$stmt = $this->conn->prepare(“SELECT cr.chat_room_id, cr.name, cr.created_at as chat_room_created_at, u.name as username, c.* FROM chat_rooms cr LEFT JOIN messages c ON c.chat_room_id = cr.chat_room_id LEFT JOIN users u ON u.user_id = c.user_id WHERE cr.chat_room_id = ?”);
$stmt->bind_param(“i”, $chat_room_id);
$stmt->execute();
// $tasks = $stmt->get_result();
$tasks = get_result( $stmt );

$stmt->close();
return $tasks;
}

// fetching multiple users by ids
public function getUsers($user_ids) {

$users = array();
if (sizeof($user_ids) > 0) {
$query = “SELECT user_id, name, email, gcm_registration_id, created_at FROM users WHERE user_id IN (“;

foreach ($user_ids as $user_id) {
$query .= $user_id . ‘,’;
}

$query = substr($query, 0, strlen($query) – 1);
$query .= ‘)’;

$stmt = $this->conn->prepare($query);
$stmt->execute();
// $result = $stmt->get_result();
$result = get_result( $stmt );

while ($user = array_shift( $result )) {
$tmp = array();
$tmp[“user_id”] = $user[‘user_id’];
$tmp[“name”] = $user[‘name’];
$tmp[“email”] = $user[’email’];
$tmp[“gcm_registration_id”] = $user[‘gcm_registration_id’];
$tmp[“created_at”] = $user[‘created_at’];
array_push($users, $tmp);
}
}

return $users;
}

In v1/index.php

/* * *
* fetching all chat rooms
*/
$app->get(‘/chat_rooms’, function() {
$response = array();
$db = new DbHandler();

// fetching all user tasks
$result = $db->getAllChatrooms();

$response[“error”] = false;
$response[“chat_rooms”] = array();

// pushing single chat room into array
while ($chat_room = array_shift( $result )) {
$tmp = array();
$tmp[“chat_room_id”] = $chat_room[“chat_room_id”];
$tmp[“name”] = $chat_room[“name”];
$tmp[“created_at”] = $chat_room[“created_at”];
array_push($response[“chat_rooms”], $tmp);
}

echoRespnse(200, $response);
});

/**
* Fetching single chat room including all the chat messages
* */
$app->get(‘/chat_rooms/:id’, function($chat_room_id) {
global $app;
$db = new DbHandler();

$result = $db->getChatRoom($chat_room_id);

$response[“error”] = false;
$response[“messages”] = array();
$response[‘chat_room’] = array();

$i = 0;
// looping through result and preparing tasks array
while ($chat_room = array_shift( $result )) {
// adding chat room node
if ($i == 0) {
$tmp = array();
$tmp[“chat_room_id”] = $chat_room[“chat_room_id”];
$tmp[“name”] = $chat_room[“name”];
$tmp[“created_at”] = $chat_room[“chat_room_created_at”];
$response[‘chat_room’] = $tmp;
}

if ($chat_room[‘user_id’] != NULL) {
// message node
$cmt = array();
$cmt[“message”] = $chat_room[“message”];
$cmt[“message_id”] = $chat_room[“message_id”];
$cmt[“created_at”] = $chat_room[“created_at”];

// user node
$user = array();
$user[‘user_id’] = $chat_room[‘user_id’];
$user[‘username’] = $chat_room[‘username’];
$cmt[‘user’] = $user;

array_push($response[“messages”], $cmt);
}
}

echoRespnse(200, $response);
});

jay gandhi
jay gandhi
4 years ago
Reply to  Alankrita

I can not understand this , you can help me what are the changes in demo.php file

CK
CK
4 years ago
Reply to  Ravi Tamada

which mysqli statements should i convert to PDO?

Ravi Tamada
4 years ago
Reply to  Yaqoub Alsaadi
Brook Bian
Brook Bian
4 years ago

Hi Ravi,

Chinese mobile phones don’t support google play. What else do you recommend except GCM?

Ravi Tamada
4 years ago
Reply to  Brook Bian

Hi Brook

I haven’t used any of the services for china. Have look at the below answer.
http://stackoverflow.com/questions/17825121/android-push-notifications-in-china

Trey Rosius
Trey Rosius
4 years ago

Hi Ravi,
What Sofware did you use to model your database tables?It really looks presentable.

Ravi Tamada
4 years ago
Reply to  Trey Rosius

It’s photoshop.

Sandeep
Sandeep
4 years ago

Hi Ravi,
There is some issue in Live Demo link, please have a look.
http://demo.androidhive.info/gcm_chat/

Ravi Tamada
4 years ago
Reply to  Sandeep

Hi Sandeep

What is the issue?. If you are getting some random alert messages, HACKERS … playing with the site. I’ll upload a fresh copy now.

Sandeep
Sandeep
4 years ago
Reply to  Ravi Tamada

it is showing some alert messages and a porn image in background.

Ravi Tamada
4 years ago
Reply to  Sandeep

Shit.. 🙁 Is it ok now? I guess It should be resolved.

Sebastian
Sebastian
4 years ago
Reply to  Ravi Tamada

Why not get msg notification when use vmware android image? But on Android Studio works fine, if I use 2 devices on Android Studio then I get only on first device msg notification… can you explain me why?

Tomas
Tomas
4 years ago
Reply to  Sebastian

maybe google play services are not installed

Sandeep
Sandeep
4 years ago
Reply to  Ravi Tamada

Yes, it is resolved now. Thanks.

Ravi Tamada
4 years ago
Reply to  Sandeep

Okay.

Marvin Collins
Marvin Collins
4 years ago

hey thanks but the api can work for me getting 404

Marvin Collins
Marvin Collins
4 years ago

come on please still getting 404 error after adding ../v1/index.php/user/login

Sebastian
Sebastian
4 years ago
Reply to  Marvin Collins

Use postman or not?

Marvin Collins
Marvin Collins
4 years ago
Reply to  Sebastian

yeah but i wanna use it on my browser it working so well with postman

Sebastian
Sebastian
4 years ago
Reply to  Marvin Collins

Ravi says “localhost/gcm_chat/v1 always gives 404. You need to access the final endpoint with the correct http method”

Ravi Tamada
4 years ago
Reply to  Marvin Collins

Browser can make http call only.

DON
DON
4 years ago

Hi Tavi Please i noticed you always use Slim version 2.3.5 I hope its safe to use it also considering that slim is now in version 3.2.1 ? please let me know because i need to built a RESTFUL app and i need to use Version 2.3.5 just like you. How is Srinivas Its been a while…

Ravi Tamada
4 years ago
Reply to  DON

I need to check the latest Slim and verify the code once as there might be lot of function deprecated. Thanks for letting me know.

DON
DON
4 years ago
Reply to  Ravi Tamada

Ok Ravi please check so i would know which way to go because i notice that to instantiate the slim is now $app = new SlimApp(); instead of $app = new SlimSlim(); in version 2.3.5 So Please Ravi Cross check so that we can know if its safe to continue with the old one or the new one.

yog
yog
4 years ago

are this source codes implement xmpp conncetion ? (for upstream purpose also ? ) i want to build app which sends data from android app to chrome extension is this possible by making some changes in this codes ?

Kunal Agrawal
Kunal Agrawal
4 years ago

hi ravi your tutorials are really helpful.i dont know how to code but with your code i made one good app. can u provide the codes for app invites via facebook,whatsapp etc would be very helpful for me i am struggling with it

David Evhade
David Evhade
4 years ago

Ravi..thanks for this tutorial. I am having an error if I type localhost/gcm_chat.. Warning: require_once(../include/db_handler.php): failed to open stream: No such file or directory in /var/www/html/gcm_chat/index.php on line 6

Fatal error: require_once(): Failed opening required ‘../include/db_handler.php’ (include_path=’.:/usr/share/php:/usr/share/pear’) in /var/www/html/gcm_chat/index.php on line 6. I am using LAMP on ubuntu. Any take?

David Evhade
David Evhade
4 years ago
Reply to  David Evhade

I have seen my error and have corrected the mistake..I mistakently thought v1/index.php is the same as index.php in the folder

FelixM
FelixM
4 years ago

Thank you for this work! 🙂
I’m trying to start app on Debian8 server, but web page don’t show me messages (Sorry! Unable to fetch topic messages), while the rest shows. Can you attach php modules that which are necessary for operation of the application?

Lina Yahi
Lina Yahi
4 years ago
Reply to  FelixM

I’m facing the same problem ” Unable to fech topic messages ” and I’m using Ubuntu. Could you tell me please if you resolved the issue ?

Rony Vidaur
Rony Vidaur
4 years ago

Hi Ravi, awesome tutorial, im still on this 1st part because when i’m trying to test it on postman the only thing that doesnt seem to be working properly is when i try to register a new user and i’ve make sure that i have the right credentials for the db, also i notice in the video when you first create the db theres a user already, it didnt happen with mine, any ideas?

Rony Vidaur
Rony Vidaur
4 years ago
Reply to  Rony Vidaur

I have solve the issue now but I dont know if this is going to affect the project works later on, what i did is modify on db_handler.php on line 28 to the following:
$stmt = $this->conn->prepare(” INSERT INTO users (name, email, gcm_registration_id,created_at) values(?, ?,”,CURRENT_TIMESTAMP)”);

let me know if that is going to give me an error, even thoug gcm_registration_id is going to be updated i assume

Kid
Kid
4 years ago
Reply to  Rony Vidaur

How Did you solve your error? Please?

David Evhade
David Evhade
4 years ago

I get this error while using this tutorial

404 Not Found

Not Found

The requested URL /gcm_chat/v1/user/login was not found on this server.

Apache/2.4.7 (Ubuntu) Server at localhost Port 80

Mohammad Goani
Mohammad Goani
4 years ago

Hi Ravi, Thanks for the Great tutorial.
I need a little help regarding ‘demo.php’ file.
I am getting an error :
Fatal error: Call to undefined method mysqli_stmt::get_result() in /home/a7612275/public_html/chattesting/demo.php on line 18.
Can u please help me with it ?

can
can
4 years ago
Reply to  Mohammad Goani

you have to setup mysqlnd on your server

CK
CK
4 years ago
Reply to  can

how do i setup mysqlnd driver on live server. I am using hostinger??

dhaval
dhaval
4 years ago
Reply to  CK

Dear
If you are using Go daddy Hosting service,Than Follow this steps:
Goto Control Panel > Software > Select PHP Version

Select Version 5 >

1. Uncheck mysqli
2. Check mark nd_mysqli

Prajwal L Sirigere
Prajwal L Sirigere
4 years ago
Reply to  dhaval

This helped me man.. 🙂

Jamal S
Jamal S
4 years ago

after adding 1 message , i get this error trying to add another message from same user

{

“error”: true,

“message”: “Failed send message Duplicate entry ‘0’ for key ‘PRIMARY'”

}

mohamed jedidi
mohamed jedidi
4 years ago
Reply to  Jamal S

just make all of the ID of database Primer key Auto Increment

Jamal S
Jamal S
4 years ago
Reply to  mohamed jedidi

Thanks mohamed , that’s just what i did to solve it , but note that u can’t do that to the chat_rooms table primary key (chat_room_id) nor the users table (user_id) since they are both used in foreign key constraint with the messages table

mohamed jedidi
mohamed jedidi
4 years ago
Reply to  Jamal S

Delete all the users chatroom and the message after that make the id of each table auto increment and creat Again the chatroom and it wel be ok

yousra
yousra
4 years ago
Reply to  mohamed jedidi

can you help me please? iam facing problem

Kid
Kid
4 years ago
Reply to  mohamed jedidi

Have a way around “oops error while registering?”

Karthi
Karthi
4 years ago

Hai Ravi,

I implemented as you said above all working good . . .

but i received the notification from who all r installing your application.i have to stop it,can you help me to do this . . .

i have changed my own API key but still i received notification from all.

Thank You 🙂

ankit vajpai
ankit vajpai
4 years ago

Hi Ravi thanku for the tutorial , I am getting some issue while connecting to MY SQL kindly help me out,

Error is as follows:
Warning: mysqli::mysqli(): (HY000/1045): Access denied for user ‘gcm’@’localhost’ (using password: YES) in C:xampphtdocsgcm_chatincludedb_connect.php on line 24

Failed to connect to MySQL: Access denied for user ‘gcm’@’localhost’ (using password: YES)

Warning: mysqli::prepare(): Couldn’t fetch mysqli in C:xampphtdocsgcm_chatdemo.php on line 41

Fatal error: Call to a member function bind_param() on null in C:xampphtdocsgcm_chatdemo.php on line 42

can
can
4 years ago
Reply to  ankit vajpai

hi! your database name and password is not same i think. check againg. you have to control database to php way

Murali Venkata Sri Sai Boliset
Murali Venkata Sri Sai Boliset
4 years ago
Reply to  ankit vajpai

check the password in your config file for the db connection. then the problem solved!!

can
can
4 years ago

hey ravi! thanks for everything this tutorial is my best. gread and educational. i have there is question. yesterday work is great but today i have error: sorry ! unable to send message.what is that ? thank for help.

can
can
4 years ago
Reply to  can

hi guys! i am working on this tutorial. i have error : sorry unable to send mesagge. but my first mesagge work perfectly bur secont mesagge i have error. why it say error i dont understand please help me. i am working only web.

can
can
4 years ago

please help me!. my first sending message is work perfectly but secont sending is not working. i have error sorry unable to send mesagge!!

Mat
Mat
4 years ago

Guys!!!!
Please recommend me IDE for PHP which is FREE and actually SUPPORTS code completition…
I have tried NET beans and Eclipse but they don’t. I only managed to use visual studio with php tools but it’s a trial….

Ravi Tamada
4 years ago
Reply to  Mat

Use NetBeans

Mat
Mat
4 years ago
Reply to  Ravi Tamada

Thanks for quick answear but it does not complite my code… Like I said only php tools for VS done the job right. Eclipse and NetBeans works fine with java code but I have non suggestions when for example typing ‘db_handler.php’ and trying to close db connection… http://imgur.com/s40MkZZ

Mat
Mat
4 years ago
Reply to  Ravi Tamada

It is not working properly…
http://imgur.com/a/uILgU

Mat
Mat
4 years ago

Here is example: http://imgur.com/s40MkZZ

Gizem Gözde
Gizem Gözde
4 years ago

hi there! i am working in this case but i have an error. i sent firt message perfectly but i again sent later web page says: sorry unable yo send message. what is that ?

yousra
yousra
4 years ago
Reply to  Gizem Gözde

me2 i face the same problem

609
0
Would love your thoughts, please comment.x
()
x