Hallo semua,, ini gw buat dokumentasi sekaligus tutorial Notifikasi Android Menggunakan Firebase (FCM)
Lumayan agak RIBET setting-annya.
1. Login akun Gmail kamu, kemudian kunjungi link ini : https://firebase.google.com/
2. Pergi ke Menu console => Kemudian Buat Proyek.
3. Pilih "Tambahkan Firebase ke Aplikasi Android Anda"
7. Jika masih ada Error di : FirebaseMessagingService tambahkan library berikut.
8. Buat 3 packages folder dengan nama app, service and utils di dalam project utama, seperti contoh gambar berikut:
Lumayan agak RIBET setting-annya.
1. Login akun Gmail kamu, kemudian kunjungi link ini : https://firebase.google.com/
2. Pergi ke Menu console => Kemudian Buat Proyek.
3. Pilih "Tambahkan Firebase ke Aplikasi Android Anda"
4. Isi Nama Package Aplikasi anda, untuk "Nama pendek" dan "Sertifikat SHA-1" di tutorial ini di abaikan saja.
5. Selanjutnya download file "google-services.json" untuk di simpan ke dalam folder app, seperti panduan pada gambar di bawah ini.
6. Tambahkan classpath ke Project-level build.gradle dan plugin ke App-level build.gradle, seperti gambar di bawah:
7. Jika masih ada Error di : FirebaseMessagingService tambahkan library berikut.
dependencies { ... compile 'com.google.firebase:firebase-messaging:9.6.0'}
8. Buat 3 packages folder dengan nama app, service and utils di dalam project utama, seperti contoh gambar berikut:
9. Download notification.mp3 dan simpan ke dalam folder res ⇒ raw. jika kamu punya pesan suara yang lain di ganti juga ngga apa2.
10. Kemudian buat class dengan nama Config.java, fungsinya untuk constant value yang nantinya akan di gunakan oleh activity yang lain.
Config.java
Config.java
package com.uneh.notif.app; /** * Created by macbookpro on 10/11/17. */ public class Config { // global topic to receive app wide push notifications public static final String TOPIC_GLOBAL = "global"; // broadcast receiver intent filters public static final String REGISTRATION_COMPLETE = "registrationComplete"; public static final String PUSH_NOTIFICATION = "pushNotification"; // id to handle the notification in the notification tray public static final int NOTIFICATION_ID = 100; public static final int NOTIFICATION_ID_BIG_IMAGE = 101; public static final String SHARED_PREF = "ah_firebase"; }
11. Buat class baru dengan nama NotificationUtils.java di dalam folder package utils.
package com.uneh.notif.until; import android.app.ActivityManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.Build; import android.support.v4.app.NotificationCompat; import android.text.Html; import android.text.TextUtils; import android.util.Patterns; import com.uneh.notif.R; import com.uneh.notif.app.Config; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; /** * Created by macbookpro on 10/11/17. */ public class NotificationUtils { private static String TAG = NotificationUtils.class.getSimpleName(); private Context mContext; public NotificationUtils(Context mContext) { this.mContext = mContext; } public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) { showNotificationMessage(title, message, timeStamp, intent, null); } public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) { // Check for empty push message if (TextUtils.isEmpty(message)) return; // notification icon final int icon = R.mipmap.ic_launcher; intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); final PendingIntent resultPendingIntent = PendingIntent.getActivity( mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT ); final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( mContext); final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + mContext.getPackageName() + "/raw/notification"); if (!TextUtils.isEmpty(imageUrl)) { if (imageUrl != null && imageUrl.length() > 4 && Patterns.WEB_URL.matcher(imageUrl).matches()) { Bitmap bitmap = getBitmapFromURL(imageUrl); if (bitmap != null) { showBigNotification(bitmap, mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound); } else { showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound); } } } else { showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound); playNotificationSound(); } } private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) { NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); inboxStyle.addLine(message); Notification notification; notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0) .setAutoCancel(true) .setContentTitle(title) .setContentIntent(resultPendingIntent) .setSound(alarmSound) .setStyle(inboxStyle) .setWhen(getTimeMilliSec(timeStamp)) .setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon)) .setContentText(message) .build(); NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(Config.NOTIFICATION_ID, notification); } private void showBigNotification(Bitmap bitmap, NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) { NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(); bigPictureStyle.setBigContentTitle(title); bigPictureStyle.setSummaryText(Html.fromHtml(message).toString()); bigPictureStyle.bigPicture(bitmap); Notification notification; notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0) .setAutoCancel(true) .setContentTitle(title) .setContentIntent(resultPendingIntent) .setSound(alarmSound) .setStyle(bigPictureStyle) .setWhen(getTimeMilliSec(timeStamp)) .setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon)) .setContentText(message) .build(); NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(Config.NOTIFICATION_ID_BIG_IMAGE, notification); } /** * Downloading push notification image before displaying it in * the notification tray */ public Bitmap getBitmapFromURL(String strURL) { try { URL url = new URL(strURL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.connect(); InputStream input = connection.getInputStream(); Bitmap myBitmap = BitmapFactory.decodeStream(input); return myBitmap; } catch (IOException e) { e.printStackTrace(); return null; } } // Playing notification sound public void playNotificationSound() { try { Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + mContext.getPackageName() + "/raw/notification"); Ringtone r = RingtoneManager.getRingtone(mContext, alarmSound); r.play(); } catch (Exception e) { e.printStackTrace(); } } /** * Method checks if the app is in background or not */ public static boolean isAppIsInBackground(Context context) { boolean isInBackground = true; ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) { ListrunningProcesses = am.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) { if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { for (String activeProcess : processInfo.pkgList) { if (activeProcess.equals(context.getPackageName())) { isInBackground = false; } } } } } else { List taskInfo = am.getRunningTasks(1); ComponentName componentInfo = taskInfo.get(0).topActivity; if (componentInfo.getPackageName().equals(context.getPackageName())) { isInBackground = false; } } return isInBackground; } // Clears notification tray messages public static void clearNotifications(Context context) { NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.cancelAll(); } public static long getTimeMilliSec(String timeStamp) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date date = format.parse(timeStamp); return date.getTime(); } catch (ParseException e) { e.printStackTrace(); } return 0; } }
12. Buat class baru dengan nama MyFirebaseInstanceIDService.java didalam folder package service.
package com.uneh.notif.service; import android.content.Intent; import android.content.SharedPreferences; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceIdService; import com.uneh.notif.app.Config; /** * Created by macbookpro on 10/11/17. */ public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService { private static final String TAG = MyFirebaseInstanceIDService.class.getSimpleName(); @Override public void onTokenRefresh() { super.onTokenRefresh(); String refreshedToken = FirebaseInstanceId.getInstance().getToken(); // Saving reg id to shared preferences storeRegIdInPref(refreshedToken); // sending reg id to your server sendRegistrationToServer(refreshedToken); // Notify UI that registration has completed, so the progress indicator can be hidden. Intent registrationComplete = new Intent(Config.REGISTRATION_COMPLETE); registrationComplete.putExtra("token", refreshedToken); LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete); } private void sendRegistrationToServer(final String token) { // sending gcm token to server Log.e(TAG, "sendRegistrationToServer: " + token); } private void storeRegIdInPref(String token) { SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0); SharedPreferences.Editor editor = pref.edit(); editor.putString("regId", token); editor.commit(); } }
13. Buat lagi class di dalam folder package service dengan nama file: MyFirebaseMessagingService.java.
package com.uneh.notif.service; import android.content.Context; import android.content.Intent; import android.support.v4.content.LocalBroadcastManager; import android.text.TextUtils; import android.util.Log; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; import com.uneh.notif.MainActivity; import com.uneh.notif.app.Config; import com.uneh.notif.until.NotificationUtils; import org.json.JSONException; import org.json.JSONObject; /** * Created by macbookpro on 10/11/17. */ public class MyFirebaseMessagingService extends FirebaseMessagingService{ private static final String TAG = MyFirebaseMessagingService.class.getSimpleName(); private NotificationUtils notificationUtils; @Override public void onMessageReceived(RemoteMessage remoteMessage) { Log.e(TAG, "From: " + remoteMessage.getFrom()); if (remoteMessage == null) return; // Check if message contains a notification payload. if (remoteMessage.getNotification() != null) { Log.e(TAG, "Notification Body: " + remoteMessage.getNotification().getBody()); handleNotification(remoteMessage.getNotification().getBody()); } // Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString()); try { JSONObject json = new JSONObject(remoteMessage.getData().toString()); handleDataMessage(json); } catch (Exception e) { Log.e(TAG, "Exception: " + e.getMessage()); } } } private void handleNotification(String message) { if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) { // app is in foreground, broadcast the push message Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION); pushNotification.putExtra("message", message); LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification); // play notification sound NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext()); notificationUtils.playNotificationSound(); }else{ // If the app is in background, firebase itself handles the notification } } private void handleDataMessage(JSONObject json) { Log.e(TAG, "push json: " + json.toString()); try { JSONObject data = json.getJSONObject("data"); String title = data.getString("title"); String message = data.getString("message"); boolean isBackground = data.getBoolean("is_background"); String imageUrl = data.getString("image"); String timestamp = data.getString("timestamp"); JSONObject payload = data.getJSONObject("payload"); Log.e(TAG, "title: " + title); Log.e(TAG, "message: " + message); Log.e(TAG, "isBackground: " + isBackground); Log.e(TAG, "payload: " + payload.toString()); Log.e(TAG, "imageUrl: " + imageUrl); Log.e(TAG, "timestamp: " + timestamp); if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) { // app is in foreground, broadcast the push message Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION); pushNotification.putExtra("message", message); LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification); // play notification sound NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext()); notificationUtils.playNotificationSound(); } else { // app is in background, show the notification in notification tray Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class); resultIntent.putExtra("message", message); // check for image attachment if (TextUtils.isEmpty(imageUrl)) { showNotificationMessage(getApplicationContext(), title, message, timestamp, resultIntent); } else { // image is present, show notification with image showNotificationMessageWithBigImage(getApplicationContext(), title, message, timestamp, resultIntent, imageUrl); } } } catch (JSONException e) { Log.e(TAG, "Json Exception: " + e.getMessage()); } catch (Exception e) { Log.e(TAG, "Exception: " + e.getMessage()); } } /** * Showing notification with text only */ private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) { notificationUtils = new NotificationUtils(context); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); notificationUtils.showNotificationMessage(title, message, timeStamp, intent); } /** * Showing notification with text and image */ private void showNotificationMessageWithBigImage(Context context, String title, String message, String timeStamp, Intent intent, String imageUrl) { notificationUtils = new NotificationUtils(context); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); notificationUtils.showNotificationMessage(title, message, timeStamp, intent, imageUrl); } }
14. Buka AndroidManifest.xml dan tambahkan service Firebase untuk class MyFirebaseMessagingService dan MyFirebaseInstanceIDService, seperti contoh di bawah:
15. Kemudian edit main_activiy untuk menampilkan reg_id firebase pada layout. buka layout file acitivy_main.xml kemudian ubah code seperti contoh di bawah ini:
16. Selanjutnya buka MainActivity.java gunakan kode seperti di bawah ini.
package com.uneh.notif; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.widget.TextView; import android.widget.Toast; import com.google.firebase.messaging.FirebaseMessaging; import com.uneh.notif.app.Config; import com.uneh.notif.until.NotificationUtils; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private BroadcastReceiver mRegistrationBroadcastReceiver; private TextView txtRegId, txtMessage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtRegId = (TextView) findViewById(R.id.txt_reg_id); txtMessage = (TextView) findViewById(R.id.txt_push_message); mRegistrationBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) { // gcm successfully registered // now subscribe to `global` topic to receive app wide notifications FirebaseMessaging.getInstance().subscribeToTopic(Config.TOPIC_GLOBAL); displayFirebaseRegId(); } else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) { // new push notification is received String message = intent.getStringExtra("message"); Toast.makeText(getApplicationContext(), "Push notification: " + message, Toast.LENGTH_LONG).show(); txtMessage.setText(message); } } }; displayFirebaseRegId(); } private void displayFirebaseRegId() { SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0); String regId = pref.getString("regId", null); Log.e(TAG, "Firebase reg id: " + regId); if (!TextUtils.isEmpty(regId)) txtRegId.setText("Firebase Reg Id: " + regId); else txtRegId.setText("Firebase Reg Id is not received yet!"); } @Override protected void onResume() { super.onResume(); // register GCM registration complete receiver LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver, new IntentFilter(Config.REGISTRATION_COMPLETE)); // register new push message receiver // by doing this, the activity will be notified each time a new message arrives LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver, new IntentFilter(Config.PUSH_NOTIFICATION)); // clear the notification area when the app is opened NotificationUtils.clearNotifications(getApplicationContext()); } @Override protected void onPause() { LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver); super.onPause(); } }
Sekarang kita sudah selesai meng-integrasikan firebase cloud messaging. sekarang jalankan project aplikasi nya, kemudian kamu lihat reg id pada logCat
ok