(Tutorial Android) Push Notification Using Firebase Cloud Messaging (Fcm)


Firebase Cloud Messaging ialah layanan push notifikasi cross-platform yang dikembangkan oleh Google yang sebelumnya menggantikan GCM, yang memungkinkan kita mengirimkan push notifikasi ke pengguna. Layanan FCM ini sepenuhnya gratis dan tidak dibatasi.

Pada tutorial kali ini saya akan membahas cara mengimplementasikan FCM di Android.

Firebase Cloud Messaging pada umumnya mempunyai beberapa tipe notifikasi. Tipe yang akan kita coba pada tutorial ini ialah Notification Message. Tipe notifikasi ini merupakan tipe yang pada umumnya dipakai untuk mengirimkan push notification.

Contoh data yang dikirimkan berupa json sebagai berikut :
{     "to": "e1w6hEbZn-8:APA91bEUIb2JewYCIiApsMu5JfI5Ak...",     "notification": {         "body": "Hello? This is push notification :)",         "title": "Push Notification",         "icon": "ic_launcher"     } } 
Kita sanggup juga menentukan kemana kita akan mengirimkan push notification tersebut. Misal kita ingin mengirim push notification ke device tertentu sanggup memakai FCM registration token dari device tersebut. Atau ke segment-segment tertentu sanggup dengan mengirimkannya ke topics di firebase.

Itu beliau sedikit penjelasannya dari saya. Nah kini kita pribadi praktek aja.

Sebelumnya buat project gres dulu di Android Studio.

Setelah selesai buat project baru, kemudian kita harus login ke firebase console. Silahkan login dulu dengan akun google agan-agan kemudian buka halaman https://firebase.google.com/ kemudian klik Go To Console.


Halaman dashboard akan tampak ibarat gambar di bawah ini. Untuk menciptakan project gres klik Add project.


Buat project gres kemudian isi Project name dan Country.


Setelah itu masuk ke sajian notification. Di sini ada 2 pilihan platform yang sanggup kita pilih, berhubung tutorial kita wacana Android maka kita pilih platform Android.


Setelah itu muncul form untuk mengisi nama package, nickname dan debug certificate SHA-1. Untuk mendapatkan debug certificate, buka terminal atau command prompt dan perintahnya sanggup lihat di https://developers.google.com/android/guides/client-auth.


Kemudian download google-services.json kemudian letakkan di dalam folder project→app.


Setelah aplikasi di daftarkan di firebase console, kemudian kita masuk ke project gres yang sudah dibuat.

Buka build.gradle pada bab Top-Level dan tambahkan dependencies berikut.
dependencies {     ...     classpath 'com.google.gms:google-services:3.1.0'     // NOTE: Do not place your application dependencies here; they belong     // in the individual module build.gradle files } 
Lalu build.gradle pada bab Module-Level tambahkan plugin dan library firebase.
dependencies {     compile fileTree(dir: 'libs', include: ['*.jar'])     compile 'com.android.support:appcompat-v7:25.0.1'     compile 'com.google.firebase:firebase-messaging:11.0.2'     testCompile 'junit:junit:4.12' } // Add to the bottom of the file apply plugin: 'com.google.gms.google-services' 
Setelah itu re-build project.

Jika agan menemukan error di bawah, mungkin Google Repository agan belum di update. Silahkan buka SDK Manager kemudian update Google Repository.


Sampai di sini kita lanjut ke bab desain layout.

Buat layout dengan nama activity_main.xml kemudian tambahkan instruksi berikut :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:id="@+id/activity_main"     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"     android:orientation="vertical"     tools:context="id.co.blogspot.andronut.android_pushnotification.MainActivity">      <ImageView         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:src="@drawable/firebase_lockup_400"         tools:ignore="ContentDescription" />      <Switch         android:id="@+id/switchNews"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:padding="16dp"         android:gravity="start"         android:checked="false"         android:text="@string/news"/>      <Switch         android:id="@+id/switchPromo"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:padding="16dp"         android:gravity="start"         android:checked="false"         android:text="@string/promo" />      <Button         android:id="@+id/btn_token"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_margin="16dp"         android:text="@string/show_token"/>      <TextView         android:id="@+id/tv_token"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:padding="16dp" />  </LinearLayout> 
Dan beberapa resources lainnya.

strings.xml
<resources>     <string name="app_name">Android-PushNotification</string>      <string name="token">Token : %s</string>     <string name="news">News</string>     <string name="promo">Promo</string>     <string name="show_token">Show Token</string>  </resources> 
colors.xml
<?xml version="1.0" encoding="utf-8"?> <resources>     <color name="colorPrimary">#FFCC01</color>     <color name="colorPrimaryDark">#FFA701</color>     <color name="colorAccent">#FF4081</color> </resources> 
Selanjutnya kita masuk ke bab coding java-nya. Buat kelas-kelas java di bawah ini :

MyFirebaseInstanceIDService.java
import android.util.Log;  import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceIdService;  /**  * Created by Wim on 7/15/17.  */  public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {      private static final String TAG = "MyFirebaseIIDService";      @Override     public void onTokenRefresh() {         // Get updated InstanceID token.         String refreshedToken = FirebaseInstanceId.getInstance().getToken();         Log.d(TAG, "Refreshed token: " + refreshedToken);          // If you want to send messages to this application instance or         // manage this apps subscriptions on the server side, send the         // Instance ID token to your app server.         sendRegistrationToServer(refreshedToken);     }      private void sendRegistrationToServer(String token) {         // TODO: Implement this method to send token to your app server.     }  } 
Kelas ini merupakan firebase service untuk mendapatkan token unik yang selalu diupdate. Nah, token inilah nantinya yang akan membedakan device satu dengan device lainnya.

MyFirebaseMessagingService.java
import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.media.RingtoneManager; import android.net.Uri; import android.support.v4.app.NotificationCompat; import android.util.Log;  import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage;  /**  * Created by Wim on 7/15/17.  */  public class MyFirebaseMessagingService extends FirebaseMessagingService {      private static final String TAG = "MyFirebaseMsgService";      @Override     public void onMessageReceived(RemoteMessage remoteMessage) {          // TODO(developer): Handle FCM messages here.         Log.d(TAG, "From: " + remoteMessage.getFrom());          // Check if message contains a data payload.         if (remoteMessage.getData().size() > 0) {             Log.d(TAG, "Message data payload: " + remoteMessage.getData());          }          // Check if message contains a notification payload.         if (remoteMessage.getNotification() != null) {             Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());             sendNotification(remoteMessage.getNotification().getBody());         }      }      private void sendNotification(String messageBody) {         Intent intent = new Intent(this, MainActivity.class);         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);         PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,                 PendingIntent.FLAG_ONE_SHOT);          Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);         NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)                 .setSmallIcon(R.mipmap.ic_launcher)                 .setContentTitle("FCM Message")                 .setContentText(messageBody)                 .setAutoCancel(true)                 .setSound(defaultSoundUri)                 .setContentIntent(pendingIntent);          NotificationManager notificationManager =                 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);          notificationManager.notify(0, notificationBuilder.build());     }  } 
Kelas ini berfungsi untuk mendapatkan message dari push notification. Message diterima melalui method onMessageReceived(RemoteMessage remoteMessage).

Lanjutkan dengan menciptakan kelas activity dengan nama MainActivity.java
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.CompoundButton; import android.widget.Switch; import android.widget.TextView; import android.widget.Toast;  import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.messaging.FirebaseMessaging;  public class MainActivity extends AppCompatActivity {      private static final String PREF_SWITCH_NEWS = "switch_news";     private static final String PREF_SWITCH_PROMO = "switch_promo";      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);           Switch switchNews = (Switch) findViewById(R.id.switchNews);         Switch switchPromo = (Switch) findViewById(R.id.switchPromo);         Button btnToken = (Button) findViewById(R.id.btn_token);          btnToken.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 String token = FirebaseInstanceId.getInstance().getToken();                 TextView tvToken = (TextView) findViewById(R.id.tv_token);                 tvToken.setText(getResources().getString(R.string.token, token));                  Log.i("TOKEN", token);             }         });          switchNews.setChecked(isSwitchChecked(PREF_SWITCH_NEWS));         switchPromo.setChecked(isSwitchChecked(PREF_SWITCH_PROMO));          switchNews.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {             @Override             public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {                 setSwitchChecked(PREF_SWITCH_NEWS, checked);                  if(checked) {                     FirebaseMessaging.getInstance().subscribeToTopic("news");                     Toast.makeText(getApplicationContext(), "Subscribe to News Topic" , Toast.LENGTH_SHORT).show();                 }else{                     FirebaseMessaging.getInstance().unsubscribeFromTopic("news");                     Toast.makeText(getApplicationContext(), "Unsubscribe from News Topic" , Toast.LENGTH_SHORT).show();                 }              }         });          switchPromo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {             @Override             public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {                 setSwitchChecked(PREF_SWITCH_PROMO, checked);                  if(checked) {                     FirebaseMessaging.getInstance().subscribeToTopic("promo");                     Toast.makeText(getApplicationContext(), "Subscribe to Promo Topic", Toast.LENGTH_SHORT).show();                 }else{                     FirebaseMessaging.getInstance().unsubscribeFromTopic("promo");                     Toast.makeText(getApplicationContext(), "Unsubscribe from Promo Topic", Toast.LENGTH_SHORT).show();                 }              }         });     }      private void setSwitchChecked(String permission, boolean isChecked) {         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);         SharedPreferences.Editor editor = preferences.edit();         editor.putBoolean(permission, isChecked);         editor.apply();     }      private boolean isSwitchChecked(String permission) {         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);         return preferences.getBoolean(permission, false);     } }  
Pada instruksi di atas, untuk men-subscibe atau men-unsubscribe ke topik yang diinginkan tinggal memanggil method :
FirebaseMessaging.getInstance().subscribeToTopic("news");  FirebaseMessaging.getInstance().unsubscribeFromTopic("news"); 
Terakhir, tambahkan service di AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="id.co.blogspot.andronut.android_pushnotification">      <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>          <!-- [START fcm_default_icon] -->         <!-- Set custom default icon. This is used when no icon is set for incoming notification messages.              See README(https://goo.gl/l4GJaQ) for more. -->         <meta-data             android:name="com.google.firebase.messaging.default_notification_icon"             android:resource="@mipmap/ic_launcher" />         <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming              notification message. See README(https://goo.gl/6BKBk7) for more. -->         <meta-data             android:name="com.google.firebase.messaging.default_notification_color"             android:resource="@color/colorAccent" />         <!-- [END fcm_default_icon] -->          <!-- [START firebase_service] -->         <service             android:name=".MyFirebaseMessagingService">             <intent-filter>                 <action android:name="com.google.firebase.MESSAGING_EVENT"/>             </intent-filter>         </service>         <!-- [END firebase_service] -->         <!-- [START firebase_iid_service] -->         <service             android:name=".MyFirebaseInstanceIDService">             <intent-filter>                 <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>             </intent-filter>         </service>         <!-- [END firebase_iid_service] -->      </application>  </manifest> 
Build dan jalankan maka tampilannya ibarat berikut.



Push Notification melalui Firebase Console

Sekarang kita akan coba mengirimkan push notification dari firebase console.


Klik Send Message, di aplikasi pribadi mendapatkan push notification.


Lalu kita tes juga mengirim push notification ke topik news.


Pada aplikasi, aktifkan pemberitahuan news maka akan mendapatkan push notification di topik news.


Push Notification melalui backend PHP

Selain dari firebase console kita juga sanggup mengirimkan push notification dari PHP. Di sini yang diharapkan ialah alamat url dan server key. Untuk melihat server key sanggup dilihat di sajian firebase console bab settings.


Copy Server key agan, kemudian buat instruksi php berikut :

index.php
<html>     <head>         <title>Firebase Cloud Messaging</title>         <meta charset="UTF-8">         <meta name="viewport" content="width=device-width, initial-scale=1.0">          <style>             input[type=text], select {                 width: 100%;                 padding: 12px 20px;                 margin: 8px 0;                 display: inline-block;                 border: 1px solid #ccc;                 border-radius: 4px;                 box-sizing: border-box;             }              input[type=submit] {                 background-color: #4CAF50;                 color: white;                 padding: 14px 20px;                 margin: 8px 0;                 border: none;                 border-radius: 4px;                 cursor: pointer;             }              input[type=submit]:hover {                 background-color: #45a049;             }          </style>              </head>     <body>         <h3>Firebase Cloud Messaging</h3>          <div>           <form action="index.php" method="get">             <label for="token">FCM Registration Token</label>             <input type="text" id="token" name="token" placeholder="Input Token">              <label for="message">Message</label>             <input type="text" id="message" name="message" placeholder="Input Message">                          <input type="hidden" name="type" value="single" >             <input type="submit" value="Kirim">           </form>                                     <form action="index.php">             <label for="fname">Topics</label>                            <select name="topics">               <option value="news">News</option>               <option value="promo">Promo</option>             </select>              <label for="lname">Message</label>             <input type="text" id="message" name="message" placeholder="Input Message">                            <input type="hidden" name="type" value="topics" >             <input type="submit" value="Kirim">           </form>                      </div>          <?php         // Enabling error reporting         error_reporting(-1);         ini_set('display_errors', 'On');           $type = isset($_GET['type']) ? $_GET['type'] : '';                  $fields = NULL;                  if($type == "single") {             $token = isset($_GET['token']) ? $_GET['token'] : '';             $message = isset($_GET['message']) ? $_GET['message'] : '';                          $res = array();             $res['body'] = $message;                          $fields = array(                 'to' => $token,                 'notification' => $res,             );                      echo 'FCM Reg Id : '. $token . '<br/>Message : ' . $message;         }else if($type == "topics") {             $topics = isset($_GET['topics']) ? $_GET['topics'] : '';             $message = isset($_GET['message']) ? $_GET['message'] : '';                          $res = array();             $res['body'] = $message;                          $fields = array(                 'to' => '/topics/' . $topics,                 'notification' => $res,             );                          echo json_encode($fields);             echo 'Topics : '. $topics . '<br/>Message : ' . $message;         }                  // Set POST variables         $url = 'https://fcm.googleapis.com/fcm/send';         $server_key = "SERVER KEY AGAN";                  $headers = array(             'Authorization: key=' . $server_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) {             echo 'Curl failed: ' . curl_error($ch);         }           // Close connection         curl_close($ch);                         ?>              </body> </html> 
Sekarang silahkan agan coba mengirim push notification. (Tested : 100% work)


Jika ingin mempelajari lebih lanjut silahkan lihat di dokumentasinya di https://firebase.google.com/docs/.

Source code lengkap sanggup dilihat di https://github.com/andronut/Android-PushNotification

Sekian dulu tutorial kali ini agar bermanfaat.
Don’t forget to share, thanks :)

Comments

Popular posts from this blog

Tugas Komplemen Terakhir

Transmisi Data

Konsep Oop Encapsulation