Friday, 10 February 2017

Android Push Notifications using Firebase Cloud Messaging (FCM), PHP and MySQL.

Friday, 10 February 2017
Android Push Notifications using Firebase Cloud Messaging (FCM), PHP and MySQL.
Holaaa guys, gimana kabar..?? haha, gue abis nonton debat Cagub terakhir barusan, dari 3 Paslon Cagub masing" punya Visi & Misi. Mereka emang udah pada tua, tapi semangat mereka belum padam buat ngerubah DKI Jakarta untuk menjadi lebih baik lagi. Klo gitu kita juga jangan mau kalah dong sama itu Orang Tua :D. Pada kesempatan kali ini gue pengen share nih, tutorial buat bikin Push Notification ato bisa disebut juga untuk pemberitahuan informasi terbaru untuk apps yang sudah ter-install ;) feature ini banyak digunain dan banyak fungsi lainnya. & gambar dibawah ini contoh siklus / cara kerja dari Push Notification menggunakan Firebase juga Php dan MySql.


Life Cycle / Scheme Of Firebase Cloud Messaging.
Penjelasan siklus untuk FCM, Pertama tama jadi Device mendaftarkan dirinya dengan Unik ID ato pada kali ini gue pake IMEI & Token bawaan dari Library Firebase yang disediain di Android. Kemudian data Device ID / IMEI & Token dikirim kan menggunakan REST  ke server untuk disimpan ke dalam database server. Dengan tujuan untuk suatu saat jika ingin memberi notifikasi pada Device tertentu jika kita membutuhkannya. Lalu, sesuai dengan kebutuhan kita, SERVER akan menjalankan perintah dengan cara manual atau secara otomatis, dan mengirimkan data ke Firebase ato FCM untuk dilanjutkan broadcasting ke Device ID yang sudah terdaftar di database server kita.

Okee kita lanjut lebih dalem lagi dan persiapkan bahan baku yang aka kita butuhin ;), kalo loe udah ada Php & MySql, coba bikin database dengan contoh Query dibawah ini.

CREATE DATABASE firebase_push_notification;

USE firebase_push_notification; 

CREATE TABLE users (
 id int(20) NOT NULL AUTO_INCREMENT,
 Token varchar(200) NOT NULL,
 Imei varchar(200) NOT NULL,
 PRIMARY KEY (id),
 UNIQUE KEY (Token)
);


Okeeey, udah jadi kan database'nya..?? lanjut ke step berikutnya, bikin file register.php dan copy paste kode dibawah ini :

<?php 
 if (isset($_POST["Token"])) {
  
     $_uv_Token=$_POST["Token"];
     $_uv_Imei=$_POST["Imei"];

     $conn = mysqli_connect("localhost","root","your_password","firebase_push_notification") or die("Error connecting");
                   $q = "INSERT INTO users (Token, Imei) VALUES ( '$_uv_Token', '$_uv_Imei') " ." ON DUPLICATE KEY UPDATE Token = '$_uv_Token';";
                   mysqli_query($conn,$q) or die(mysqli_error($conn));
                   mysqli_close($conn);

 }
 ?>


Kode diatas digunakan untuk mendaftarkan Device ID ke database. Jangan lupa config'nya disesuaikan dengan settingan komputer agan ;)

Kemudian kalo sudah jadi file'nya, kita buat file selanjutnya yang bernama push_notification.php file ini bertujuan untuk membuat notifikasi dan mengirimkan data Device ID dan Pesan yang akan dikirim ke server Firebase dan lalu Firebase melakukan Broadcasting ke Device ID tujuan. Kode'nya kira kira seperti dibawah ini :

<?php 
 function send_notification ($tokens, $message)
 {
  $url = 'https://fcm.googleapis.com/fcm/send';
  $fields = array(
    'registration_ids' => $tokens,
    'data' => $message
   );

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

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
        $result = curl_exec($ch);           
        if ($result === FALSE) {
           die('Curl failed: ' . curl_error($ch));
        }
        curl_close($ch);
        return $result;
 }
 
 $conn = mysqli_connect("localhost","root","your_password","firebase_push_notification");

 $sql = " Select Token From users";

 $result = mysqli_query($conn,$sql);
 $tokens = array();

 if(mysqli_num_rows($result) > 0 ){

  while ($row = mysqli_fetch_assoc($result)) {
   $tokens[] = $row["Token"];
  }
 }

 mysqli_close($conn);

 $message = array("message" => " TESETERRRRR !!!");
 $message_status = send_notification($tokens, $message);
 echo $message_status;
 ?>

Untuk bagian server key kalo gak tau posisinya, dibawah ini screenshoot dari halaman Firebase ini https://console.firebase.google.com/project/the-fucker-747/settings/cloudmessaging dan ini contoh screenshoot'nya :

Screenshoot Server Key

Nahhh, bimmmsalabimmm dan jadilah server yang siap membroadcast notifikasi. Dan kita akan melanjutkan ke tahap berikutnya nih. dan kita akan masuk ke kodingan android, yang lumayan sederhana tapi berguna buat belajar kita kali ini.

Okeee, belom capek kan..? baca'nya hehhe. ato pergi dulu sono bikin kopi terus balik lanjutin tugas kita untuk merubah dunia hhahahahha.

Lanjut ke android'nya nih, yaa tau dong kita musti ngapain..?? siapin project kosong aja di android studio, File > New > New Project trus di sesuaikan deh nama packages dan pilih template Blank Activity kalo dikasih pilihan, dan klik finish. tunggu beberapa saat.

Kemudian ada perubahan dikit di file build.gradle kita akan menambahkan library'nya si firebase dulu.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.google.firebase:firebase-messaging:9.0.1'
    compile 'com.android.support:design:23.4.0'
    compile 'com.squareup.okhttp3:okhttp:3.2.0'
}

// INI WAJIB KALO KAGAK ERROR
apply plugin: 'com.google.gms.google-services'


Nah lanjut lagi ke AndroidManifest.xml kita rubah juga seperti kode xml dibawah ini :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.bye.project">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".FirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>


        <service
            android:name=".FirebaseInstanceIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>

    </application>
</manifest>

Nah udah dicopy kannn..??? mari kita lanjut membuat file MainActivity.java kita copy aja langsung kode dibawah ini biar gak terjadi kesalah pahaman diantara kita ;)

package com.bye.project;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.telephony.TelephonyManager;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;
import com.bye.project.R;

/**
 * Created by webster on 2/11/2017.
 */
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        int permissionCheck = ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE);

        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_PHONE_STATE}, 1);
        }

        FirebaseMessaging.getInstance().subscribeToTopic("test");
        FirebaseInstanceId.getInstance().getToken();

    }
}


Nahhh dibagian file FirebaseInstanceIDService.java ini , adalah file yang berisi function buat kirim data ke server dan perhatiin potongan kodenya, jangan kopi paste doang donk wooooo !!!
package com.bye.project;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

import java.io.IOException;

import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * Created by webster on 2/11/2017.
 */
public class FirebaseInstanceIDService extends FirebaseInstanceIdService implements ActivityCompat.OnRequestPermissionsResultCallback {
    private static final String TAG = "FirebaseInstanceIDService";

    public String imei;
    @Override
    public void onTokenRefresh() {
        String token = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token : " + token);
        registerToken(token);
    }

    private void registerToken(String token) {

        TelephonyManager mngr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
        imei = mngr.getDeviceId();

        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
                .add("Token",token)
                .add("Imei", imei)
                .build();

        Request request = new Request.Builder()
                .url("http://localhost/FirebasePushNotificationThree/register.php")
                .post(body)
                .build();

        try {
            client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1:
                if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    //TODO
                }
                break;

            default:
                break;
        }
    }

}


Nahhh kali yang ini bernama file FirebaseMessagingService.java , berguna untuk Listener atau penerima notifikasi secara async, Copy Paste ajaa langsung vrohh .

package com.bye.project;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import com.bye.project.R;

import com.google.firebase.messaging.RemoteMessage;

/**
 * Created by webster on 2/11/2017.
 */
public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService{

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        showNotification(remoteMessage.getData().get("message"));
    }

    private void showNotification(String message) {

        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setAutoCancel(true)
                .setContentTitle("FCM Test")
                .setContentText(message)
                .setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
                .setContentIntent(pendingIntent);

        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        manager.notify(0,builder.build());
    }


}


Aduuhhhhh gue hampir lupa buat bikin file activity_main.xml yang dibutuhin di file MainActivity.java

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Tungguiiiin Sampe Token Masuk Ke Database !"
        android:id="@+id/textView" />
</RelativeLayout>


Nah kalo persiapan udah semua..??? cobaa running dulu aplikasi android'nya.. dan kalo udah selesai coba buka halaman ini http://localhost/FirebasePushNotificationThree/push_notification.php

dan kalo muncul tampilan seperti ini success 1 / failure : 0 itu tandanya gak ada masalah dan aplikasi FCM berjalan dengan sempurna tanpa ada halangan & lancar jaya ;)

{"multicast_id":8610617751155849547,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1486747301765964%2c030b2cf9fd7ecd"},{"message_id":"0:1486747301783453%2c030b2cf9fd7ecd"}]}

Ini Screenshot dari PR kita malam ini ;)

GITHUB !

No comments:

Post a Comment

Bye Webster | Kebanggaan dari keburukan diri sendiri adalah penyesalan yang belum saatnya ! © 2016