Android Push Notification Firebase Cloud Message

Merhaba arkadaşlar bu yazımızda mobil uygulamalarda en çok kullanılan bildirim gönderme işleminin nasıl yapıldığı hakkında bilgi vereceğim. Yazımız biraz uzun olacak fakat .Net servisini kullananlar için büyük bir kaynak olacağını düşünüyorum. Bildirim gönderme işlemi için bir çok sağlayıcı bulunmaktadır. Ben google destekli olan Firebase kullanacağım.

Öncelikle android studio üzerinde yeni bir proje oluşturuyoruz.  İkinci adım olarak Firebase hesabı oluşturuyoruz. Daha sonra Create New Project tıklayarak yeni proje ekliyoruz.

firebase-create-new-project

Projemizi ekledikten sonra Add Firebase to your Android app seçeneğini tıklayarak projemize uygulamamızı ekliyoruz.

firebase-console-overview

Android uygulamamızdan package com.caglartelef.deneme; paket adını kopyalayarak Enter app details ekranında Package name alanına yapıştırıyoruz.

add-firebase-android-app-1

Add app butonuna tıklayarak bir sonraki ekrana geçiyoruz. Bu ekranda bizim için hazırlanmış olan bir google-services.json dosyasını otomatik olarak indiriyor.

add-firebase-android-app-2

Bu dosyayı android studio da oluşturduğumuz uygulamamız içerisinde Project Files>>>app>>>app dosyanın altına atıyoruz.

project-files-app

Continue butonuna tıklayarak son ekrana geçiş yapıyoruz. Ekranda bulunan 1. Project-level build.gradle bölümü altındaki

classpath 'com.google.gms:google-services:3.0.0' kopyalayarak android studiodaki uygulamamızı açarak build.gradle(Project) dosyanını açarak dependencies  içerisinde yapıştırıyoruz.

2. App-level build.gradle(Modüle) bölümü altındaki

apply plugin: 'com.google.gms.google-services' kopyalayarak android studiodaki uygulamamızı açarak build.gradle(Modüle) dosyasını açarak dependencies parantezlerinden sonraki alana yapıştırıyoruz.
Daha sonra uygulam içerisinde kullanacağımız kütüphaneleri de ekliyoruz. Son olarak aşağıdaki şekilde olmalıdır.
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.google.firebase:firebase-messaging:9.0.0'
    compile 'com.squareup.okhttp3:okhttp:3.2.0'
}
apply plugin: 'com.google.gms.google-services'
Değişikliklerin uygulanabilmesi için Sync now diyoruz. Arkadaşlar burada en önemli olan bölüm sürüm versiyonlarıdır. Dikkat ediniz.

Firebase tarafındaki tüm işlemleri yaptıktan sonra android uygulamamızı açarak kodlama işlemine başlıyoruz.

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;
public class MainActivity extends AppCompatActivity {
 private static final String TAG="MainActivity";
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 FirebaseMessaging.getInstance().subscribeToTopic("test");
 FirebaseInstanceId.getInstance().getToken();
 }
}

Öncelikle MainActivity içerisine aşağıdaki kodları kopyalıyıp yapıştırıyoruz. Paket adınızı silmeyiniz. Daha sonra  MyFirebaseInstanceIDService adından bir sınıf ekliyoruz. Bu sınıfımız FirebaseInstanceIdService sınıfında extends edilmektedir. Aşağıdaki kodları kopyalayıp yapıştırabilirsiniz.

import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
    private static final String TAG="MyFirebaseIIDService";
    @Override
    public void onTokenRefresh(){
        String refreshedToken= FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG,"Refreshed token: "+refreshedToken);
        //TODO:Implement this method to send any registration to your app's servers.
        sendRegistrationToServer(refreshedToken);
    }
    private void sendRegistrationToServer(final String token){
        //TODO:Add custom implementation, as needed.
        Log.d(TAG,"sendRegistrationToServer: "+token);
        sendIdToServer(token);
    }
    private void sendIdToServer(String token) {/*Bu alanda tokenları veritabanına kaydediyoruz. Kaydetme işleminde ise .Net platformu kullandım. Bu alanı kullandığınız servise göre şekillendiriniz.*/
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
        .url("https://servisim.com/WS/register.aspx?Token="+token)
        .build();
try {
    client.newCall(request).execute();
} catch (IOException e) {
    e.printStackTrace();
}
}
}

Bu sınıfıda  ekledikten sonra MyFirebaseMessagingService adında yeni bir sınıf ekliyoruz ve bu sınıfımızda FirebaseMessagingService sınıfından extends edilmektedir.

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;
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());
        Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
        sendNotification(remoteMessage.getNotification().getBody());
    }
    private void sendNotification(String messageBody) {/*Gelen bildirimi göstermek için özelleştiriyoruz.*/
        Intent intent = new Intent(this, Login.class);/*Bildirime tıklandığında açılacak activity yazıyoruz.*/
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.notification)/*33x33 boyutunda png dosyası yeterli olmaktadır.*/
                .setContentTitle("FCM Message")/* Başlık*/
                .setContentText(messageBody)/*Gelen bildirim mesajı*/
                .setStyle(new NotificationCompat.BigTextStyle())/*Bildirim stili*/
                .setAutoCancel(true)
                .setSound(defaultSoundUri)/*Bildirim sesi*/
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, notificationBuilder.build());
    }
}

Uygulamamız Firebase web sayfasından bildirim göndermek için hazır. Uygulamayı çalıştıralım ve Android Monitor e tıklayalım ve logcat bölümünü açalım. Token bilgisini kopyalayalım. Bu token bilgisi her seferinde değişiklik gösterebilmektedir.

logcat

Arkadaşlar şuan Firebase web sayfasından bildirim gönderebiliriz. Bunun için sayfayı açıyoruz ve notification butonuna tıklıyoruz. Send Your First Message butonuna tıklıyoruz.

send-notification

Mesajımızı yazıyoruz. Target bölümünden Single Device tıklayarak FCM registration token bölüne token bilgisini yapıştırıyoruz. Send Message butonuna tıkladığımızda telefonumuza bildirim gönderilmektedir.

Arkadaşlar buraya kadar olan kısım kolaydı. Çünkü bununla ilgili bilgileri her yerde bulabilirsiniz. Şimdi bu bildirim işini otomatik hale getirebilmek için ne yapacağız. Yukarıda bahsettiğim gibi ben .Net kullandım ve bununla ilgili çok az kaynak bulabildim. Php ve MySql için bir çok kaynak bulunmaktadır.

.Net platformunda register.aspx sayfası oluşturuyoruz. Sayfanın load olayına yani sayfaya request geldiğinde sayfa yüklenmeye başladığı anda çalışacak kodları yapıştırıyoruz. Bu kodlar gelen Requestle QueryString’i alıyoruz ve veritabanına kaydediyoruz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Fcm
{
 public partial class register : System.Web.UI.Page
 {
 string Token = "", Mesaj = "Test Mesajı";
 protected void Page_Load(object sender, EventArgs e)
 {
 /**
 * Sayfanın Load eventinde Querystring ile gelene token i yakalayarak token ye eşitliyoruz.
 * AndroidGCMPushNotification adında oluşturduğumuz classa token ve mesajımızı gönderiyoruz.
 * AndroidGCMPushNotification classı Google Fcm servisine token ve mesajı gönderiyor.
 * Google fcm servisi gönderilen token a sahip olan cihaza notification gönderiyor.
 */
 /**
 * Querystring aşağıdaki gibi gelmesi beklenmektedir.
 * 
 * http://www.xxx.com/register.aspx?Token=123456789
 */

if (!IsPostBack)
 {
 try
 {
 Token = Request.QueryString["Token"].ToString();/*Querystring de gelen Token değerini Token değişkenine atıyoruz.*/
 }
 catch (NullReferenceException ex){ }
 }
 if (Token.Length > 0)
 {
 AndroidGCMPushNotification fcm = new AndroidGCMPushNotification();
 fcm.SendNotificationJson(Token, Mesaj);
 }
 }
 }
}

Arkadaşlar şimdi gelen bu token adresini kayıt ettik fakat şuan uygulamaya bildirim gitmedi. Uygulamaya bildirim gitmesi için Firebase Cloud Message servisiyle haberleşmeliyiz.

Bunun için aşağıdaki işlemleri yapıyoruz. AndroidGCMPushNotification adında bir sınıf oluşturuyoruz. Daha sonra Nuget Managerden Newtonsoft Json ekliyoruz.

Örnek olarak aşağıdaki json objesinin c# kodu haline çevirme işlemi için zorlanıyorsanız lütfen tıklayınız.

{
"to":"device_id",
"notification":{
 "title":"FCM Message",
 "text":"Test mesajı"
 },
}

Otomatik olarak oluşturma işlemini yaptıktan sonra aşağıki gibi olmalıdır.

public class AndroidGCMPushNotification
 {

public class Notification
 {
 public string title { get; set; }
 public string text { get; set; }
 }

public class Example
 {
 public string to { get; set; }
 public Notification notification { get; set; }
 }

public string SendNotificationJson(string id, string msg)
 {
 
 var AuthString = "***************************";/*İlgili açıklama aşağıda yapılmıştır.*/
 var RegistrationID = id;
 var Message = msg;
 //-- Firebase Cloud Message HttpWebRequest oluşturuyoruz. --//
 HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://fcm.googleapis.com/fcm/send");
 Request.Method = "POST";
 Request.KeepAlive = false;

 Example ex = new Example();
 ex.to = id;
 Notification note = new Notification { title="Bildirim",text=msg };
 ex.notification = note;
 string postData = JsonConvert.SerializeObject(ex);/*FCM için json objesine dönüşüm yapıyoruz.*/
 byte[] byteArray = Encoding.UTF8.GetBytes(postData);/*byte dizisi haline getiriyoruz*/
 Request.ContentType = "application/json;charset=UTF-8";/*Request content tipini json olarak belirtiyoruz.*/
 Request.ContentLength = byteArray.Length;
 Request.Headers.Add(string.Format("Authorization:key={0}", AuthString));
 //-- Delegate kullanarak Server sertifikasını onayladık --//
 ServicePointManager.ServerCertificateValidationCallback += delegate (
 object
 sender,
 System.Security.Cryptography.X509Certificates.X509Certificate
 pCertificate,
 System.Security.Cryptography.X509Certificates.X509Chain pChain,
 System.Net.Security.SslPolicyErrors pSSLPolicyErrors)
 {
 return true;
 };

//-- Stream nesnesi oluşturduk ve byte dizisini yazdırdık. --// 
 Stream dataStream = Request.GetRequestStream();
 dataStream.Write(byteArray, 0, byteArray.Length);
 dataStream.Close();

//-- Mesajı gönderdik --//
 WebResponse Response = Request.GetResponse();
 HttpStatusCode ResponseCode = ((HttpWebResponse)Response).StatusCode;/*Gelen mesajı kodunu aldık.*/
 if (ResponseCode.Equals(HttpStatusCode.Unauthorized) || ResponseCode.Equals(HttpStatusCode.Forbidden))
 {
 return "Unauthorized - need new token";/*Token FCm tarafından devre dışı kalmıştır.*/

}
 else if (!ResponseCode.Equals(HttpStatusCode.OK))
 {
 return "Response from web service isn't OK";/*Mesaj onaylanmamıştır.*/
 }

 StreamReader Reader = new StreamReader(Response.GetResponseStream());
 string responseLine = Reader.ReadLine();
 string result = Reader.ReadToEnd();
 Reader.Close();
 return result;
 }

}

AutString almak için Firebase web sayfasını açıyoruz ve  overview yani anasayfa ekranına geliyoruz. Manage butonuna tıklıyoruz.

firebase-manage

Açılan ayarlar sayfasından Cloud Messaging bölümüne geçiyoruz ve Server Key değerini kopyalıyoruz. Bu değer bizim AutString değerimiz oluyor.

cloudmessage

Arkadaşlar tüm bu işlemleri tamamladıktan sonra uygulamamız açıldığında FCM sisteminden token alıyor daha sonra bizde bu token bilgisini kullanarak kullanıcıya otomatik olarak bildirim gönderebilmekteyiz. Bu işlemleri kendinize göre özelleştirebilirsiniz.

.NET servisi kaynak kodlarını indirmek için TIKLAYINIZ.