Site icon Mobilhanem

Android Firebase Cloud Messaging ile Push Notification Göndermek

Merhaba Arkadaşlar,
mobilhanem.com üzerinden anlattığımız/yayınladığımız android uygulama geliştirme derslerine Firebase Cloud Messaging ile devam ediyoruz. Firebase Cloud Messaging yani FCM , Google Cloud Messaging push servisinin yeni versiyonudur. Google yeni uygulamalara ve GCM kullanan uygulamalara Firebase kullanılması yönünde tavsiyede bulunmaktadır.Google Cloud Messaging sayfasına girdiğinizde sayfanın üstünde bu uyarıyı görebilirsiniz.

Firebase Cloud Messaging

Gelelim FCM ‘i uygulamamıza nasıl entegre edeceğimize. Ben tüm adımları detaylı bir biçimde anlatmaya çalışacağım.Dolayısıyla uzun bir yazı olacaktır. Öncelikle bu linke tıklayarak Firebase konsolumuza giriyoruz. Gmail hesabımız ile login oluyoruz.

Firebase Konsol Ayarları

 

 

Sonra karşımıza çıkan ekranda Create New Project butonuna tıklıyoruz.

 

 

 

 

 

Açılan popupta  projemize isim veriyor  ülkemizi seçiyoruz ve Create Project butonu ile devam ediyoruz.

 

 

 

 

 

 

 

Açılan sayfada farklı farklı firebase servisleri var. Biz Notifications olanı seçiyor ve Get Started Linkine tıklıyoruz.

 

 

 

 

 

 

 

Android iconuna tıklayarak devam ediyoruz.

 

 

 

Açılan popupta ilk alana packagename alanına oluşturduğumuz uygulamanın package name adını giriyor ,ikinci alanı boş bırakıyor ve ADD APP diyerek devam ediyoruz.

 

 

 

 

 

 

 

Otomatik olarak bilgisayarımız inen google-services.json dosyamızı Android Projemizde nereye eklememiz gerektiğini göstermektedir. Continue diyerek devam ediyoruz.

 

 

 

 

 

 

Build.gradle’da yapmamız gereken değişiklikleri gösteriyor. Burda bizden gradle dosyamıza eklememiz gereken kodları gösteriyor.

 

 

 

Android Ayarları

Öncelikle yukarıdaki adımları izlerken otomatik olarak inen google-services.json dosyamızı buluyoruz. Bu dosyayı projemizin bulunduğu klasörde app klasörünün içine yerleştiriyoruz. Aksi takdirde google-services.json dosyasını bulamadım hatası alıyoruz. Yukarıdaki resimlerde zaten bu adımı anlatıyor. Sonrasında uygulamamızı refresh ediyoruz.

 

 

Eğer Android Studio’da  google-services.json klasörünü eklemiş olmamıza rağmen dizinde gözükmüyorsa Project viewer’ımızı değiştiriyoruz. Ve sadece Project olanı seçiyoruz.

 

 

 

Sonra build.gradle dosyamızı açıp bize söylediği scriptleri ekliyoruz. Öncelikle Projenin root dizininde bulunan build.gradle’mızı açıyoruz(Yanında Project:ProjeAdınız yazan build.gradle dosyamız). dependencies içine aşağıdaki gibi düzenleyip “com.google.gms:google-services:3.0.0” satırını ekliyoruz.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0'
        classpath 'com.google.gms:google-services:3.0.0'


        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

Sonra app klasörümüz içinde olan build.gradle dosyamızı açıyoruz(yanında Module:app yazan build gradle dosyamız). Bunun içine ise “apply plugin: ‘com.google.gms.google-services'” ve dependencies kısmına ise “compile ‘com.google.firebase:firebase-messaging:9.6.1’
” satırlarını ekleyeceğiz. Aşağıda oluşturduğum gradle dosyasını inceleyebilirsiniz.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"
    defaultConfig {
        applicationId "com.mobilhanem.firebasepush"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:24.2.1'
    compile 'com.google.firebase:firebase-messaging:9.6.1' //Firebase Meesaging library

    // Testing dependencies
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2'
    androidTestCompile 'com.android.support.test:runner:0.5'
    androidTestCompile 'com.android.support:support-annotations:24.2.1'

}
apply plugin: 'com.google.gms.google-services'

Not: “apply plugin: ‘com.google.gms.google-services’ ”  bu kodu en alta eklemeye dikkat edelim aksi takdirde MultiDex hatası alacaksınız.

Gradle ayarlarımızı yaptıktan sonra projemizi Sync etmeyi unutmayalım.

Yukarıdaki gibi ayarlarımızı yaptıktan sonra Projemize iki adet Class ekleyeceğiz. Bu classlardan birincisi FirebaseInstanceIdService class’ına extend edecek diğeri ise FirebaseMessagingService class’ına extend edecek. FirebaseInstanceIdService class’ı ve FirebaseMessagingService’i class’ı build.gradle’ın dependencies kısmına eklediğimiz Firebase-messaging kütüphanesi ile projemize dahil oldu. Bu iki class’ta Service Class’lardır. Yani uygulamanın arka planında çalışmaktadırlar. Android Service Class’lar hakkında detaylı bilgiyi bu yazımızdan bulabilirsiniz.

Öncelikle bu service classlarımızı AndroidManifest.xml dosyamıza ekleyelim. İsimlerini Google’n örnek projesinde verdiği gibi MyFirebaseInstanceIdService ve MyFirebaseMessagingService verelim. Ne iş yaptıklarını ise kodlarını paylaştıktan sonra anlatalım 🙂

AndroidManifest.xml  :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mobilhanem.firebasepush">

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

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

        <!-- [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>

 

MyFirebaseInstanceIdService :

package com.mobilhanem.firebasepush;

import android.util.Log;

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

/**
 * Created by tahakirca on 29/09/16.
 */

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService{

    private static final String TAG = "MyFirebaseIIDService";
    
    @Override
    public void onTokenRefresh() {
        String token = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Token: " + token);

        sendRegistrationToServer(token);
    }

    private void sendRegistrationToServer(String token) {
        // token'ı servise gönderme işlemlerini bu methodda yapmalısınız
    }

}

Yukarıdaki class bir Service class olduğu için kendisi otomatik çalışacaktır ve içindeki onTokenRefresh() methodu uygulama ilk kurulduğunda , Token oluştuğu zaman otomatik olarak çağırılacaktır. onTokenRefresh() methodu sadece uygulama ilk kurulduğunda çalışmaz. Firebase ,token değiştiği zamanda otomatik olarak bu methodu çağıracaktır.  Log.d kullanarak oluşan Token’ı yazdırdık ayrıca Toast mesajı olarak bastırdık. Bu Token sizin cihazınıza özel bir unique token’dır ve notifikasyon gönderilirken bu token sayesinde sizin cihazınıza notifikasyon gönderilmektedir. Oluşan token’ı  sendRegistrationToServer methoduna gönderdik. Bu methodda oluşmuş olan token’ı servisimize gönderme işlemlerini yapmalısınız. Bunu Asynctask , volley kütüphanesi veya Retrofit kütüphanelerini ile yapabilirsiniz. Bu yapıyı nasıl kuracağınıza siz karar verebilirsiniz.

FirebaseMessagingService :

FirebaseMessagingService kodlarını paylaşmadan önce Firebase Cloud Messaging sistemindeki mesaj tiplerinden bahseledim. Firebase’n 2 farklı tip mesaj çeşidi bulunmaktadır. 1. tip Notification mesaj ve 2.tip Data mesaj olarak ayrılmaktadır.
1-Notification Mesaj
Notification mesaj direk Firebase SDK tarafından handle edilir.Yani uygulamamıza eklediğimiz SDK bizim yerimize notifikasyon gösterme işlemini yapmaktadır. Uygulama arka planda(background) ise notification mesaj geldiği an bizim uygulamamız içinde birşey yapmamıza gerek kalmıyor. Firebase otomatik olarak notification mesajını ve uygulama iconunu göstermekte ve notifikasyona tıklandığında uygulamamız açmaktadır.

Not: Firebase console’dan sadece Notification mesaj gönderilebilmektedir. Data mesaj için Server kullanmanız gerekmektedir. Server’dan hem notification mesaj hemde data mesaj gönderebilirsiniz.Firebase console’dan gönderilen mesajda Notifikasyon sesi çıkmamaktadır.

Server’dan aşağıdaki şekilde notification mesaj gönderebilirsiniz.

{
    "to": "eusmFiZt93g:APA91bEvR-WpbK4A5xwYk3OYKr4-Es .. ", //(Firebase Token)
    "notification": { // notification mesaj tipi
        "body": "Merhaba , Mobilhanem kullanıcıları. Bu bir notifikasyon mesajıdır.", 
        "title": "Mobilhanem.com"
    }
}

2-Data Mesaj

Bu mesaj tipinde ise aşağıdaki paylaşacağım FirebaseMessagingService class’ın onMessageReceived methodu tetiklenmektedir. Yani uygulama ön planda(foreground) veya arka planda(background) olması farketmez. Uygulamada notifikasyon gösterme, notifikasyon sesi,notifikasyon iconu vs.. uygulama içinde uygulamayı yazan kişi tarafından yapılmaktadır. Bu mesaj tipi ile farklı datalarda göndermek mümkündür. Bu dataları onMessageReceived methodu içinde handle edip uygulama içinde istediğimiz gibi kullanabiliriz. Notifikasyon göstermek zorunda da değiliz. İstersek sadece gelen datayı uygulama içinde kullanabiliriz.

Google Cloud Messaging dersimde en çok gelen sorulardan biri notifikasyon olarak gönderilen linki uygulama içinde açtırmaktı. İşte data mesaj tipi bunun kullanımına örnek olabilir.

{
    "to": "eusmFiZt93g:APA91bEvR-WpbK4A5xwYk3OYKr4-Es .. ", //(Firebase Token)

    "data": { // data mesaj tipi
        "site_adi": "Mobilhanem.com", 
        "link": "https://www.mobilhanem.com"
    }
}

onMessageReceived() methodu içinde  remoteMessage.getData() ile gönderilen bilgileri alıp uygulama içinde istediğimiz gibi kullanabiliriz.

Ayrıca yukarıdaki farklı iki mesaj tipini tek bir mesaj içindede aşağıdaki gibi gönderebiliriz.

{
    "to": "eusmFiZt93g:APA91bEvR-WpbK4A5xwYk3OYKr4-Es .. ", //(Firebase Token)
    "notification": { // notification mesaj tipi
        "body": "Merhaba , Mobilhanem kullanıcıları. Bu bir notifikasyon mesajıdır.", 
        "title": "Mobilhanem.com"
    },
    "data": { // data mesaj tipi
        "site_adi": "Mobilhanem.com", 
        "link": "https://www.mobilhanem.com"
    }

}

Gelelim FirebaseMessagingService class’ımıza:

package com.mobilhanem.firebasepush;

/**
 * Created by tahakirca on 29/09/16.
 */
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.media.Ringtone;
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) {

        if (remoteMessage.getData().size() > 0) { // Data mesajı içeriyor mu
            //Uygulama arkaplanda veya ön planda olması farketmez. Her zaman çağırılacaktır.
            //Gelen içerik json formatındadır.
            Log.d(TAG, "Mesaj data içeriği: " + remoteMessage.getData());
            
            //Json formatındaki datayı parse edip kullanabiliriz. Biz direk datayı Push Notification olarak bastırıyoruz

            sendNotification("Mobilhanem.com",""+remoteMessage.getData());

        }

        if (remoteMessage.getNotification() != null) { //Notification mesajı içeriyor mu
            //Uygulama arkaplanda ise burası çağrılmaz.Ön planda ise notification mesajı geldiğinde çağırılır
            //getBody() ile mesaj içeriği
            //getTitle() ile mesaj başlığı
            Log.d(TAG, "Mesaj Notification Başlığı: " + remoteMessage.getNotification().getTitle() +" "+"Mesaj Notification İçeriği: " + remoteMessage.getNotification().getBody() );

            //Gelen içeriğe göre notifikasyon bildiriminde bulunma
            sendNotification(remoteMessage.getNotification().getTitle(),remoteMessage.getNotification().getBody());
        }

    }

    private void sendNotification(String messageTitle,String messageBody) {

        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        long[] pattern = {500,500,500,500};//Titreşim ayarı

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setVibrate(pattern)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        try {
            Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
                    + "://" + this.getPackageName() + "/raw/notification");
            Ringtone r = RingtoneManager.getRingtone(this, alarmSound);
            r.play();
        } catch (Exception e) {
            e.printStackTrace();
        }

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}

Evet arkadaşlar android ayarları bukadar. Gelelim Notifikasyon nasıl göndereceğimize:

Firebase Panel Kullanarak Notifikasyon Gönderme

Firebase Cloud Messaging ile gelen yeniliklerden biride Firebase paneli kullanarak push notification atabilmemiz. Yukarıda da belirttiğim gibi Firebase panel kullanarak sadece Notification tipinde mesaj gönderebilirsiniz.Uygulama arka planda ise Firebase SDK kendisi notifikasyon çıkarmaktadır. Eğer ön planda ise uygulama onMessageReceived() methodu içinde kendimiz handle edip notifikasyon işlemlerini kendimiz yapabiliriz.

https://console.firebase.google.com/?hl=tr adresine girerek oluşturduğumuz uygulamayı seçiyoruz. Sol taraftaki menüden Notifications kısmını seçip açılan sayfadan New Message diyerek aşağıdaki sayfayı açıyoruz ve aşağıdaki şekilde bilgileri doldurduktan sonra SEND MESSAGE ile göndere tıklıyoruz.

Böylelikle telefonunda uygulamamız kurulu olan cihazlara notification tipinde notifikasyonlarımızı ServerSide olmadan göndermiş oluyoruz.

Server Side Kullanarak Notifikasyon Göndermek

Server Side kullanarak hem notification tipinde hemde data tipinde notifikasyonlar gönderebiliriz.

Önce Server Side’dan notifikasyon göndermemiz için gerekli olan Web API Key’imizi Firebase konsolundan almamız gerekiyor.https://console.firebase.google.com/?hl=tr adresine girerek oluşturduğumuz uygulamayı seçiyoruz.

 

 

Sonra sol üstteki uygulama adımızın yanında bulunan ayarlar iconuna tıklıyor ve Project settings’e tıklıyoruz.

 

 

Açılan sayfada Web API Key karşısında bulunan uzun string bizim API key’imiz oluyor.

 

 

Gelelim PHP’den Notifikasyon göndermeye:

        $firebase_url = 'https://fcm.googleapis.com/fcm/send';
		
	$fields = array(
            'to' => $token, //KULLANICI TOKEN -> Kullanıcı telefonunda oluşan Token
            'notification' => array('title' => 'Mobilhanem.com', 'body' => 'Mobilhanem.com Firebase Push Mesaj'), //Notification tipinde mesaj
            'data' => array('site_adi' => 'Mobilhanem.com','site_linki'=>'https://www.mobilhanem.com') //data tipinde mesaj
        );
 
        $headers = array(
            'Authorization:key=' . SERVER_KEY, //SERVER API KEY -> Konsoldan aldık
            'Content-Type:application/json'
        );		
		$ch = curl_init();
 
        curl_setopt($ch, CURLOPT_URL, $firebase_url); 
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
    
        $result = curl_exec($ch);
       
        curl_close($ch);

 

Bilgisayarımızın Konsolundan Notifikasyon Göndermek (Curl)

//SERVER_API_KEY -> Firebase konsoldan aldığımız WEB_API_KEY
//USER_TOKEN -> Kullanıcı Push token 

curl -X POST --header "Authorization: key= SERVER_API_KEY" --Header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d "{\"to\":\"USER_TOKEN\",\"notification\":{\"body\":\"mobilhanem.com\"} }"


Yukarıdaki satırda notification kısmını data yaparak data tipindede mesajlar gönderebilirsiniz.

Not: Kendi google-services.json dosyanızı dahil etmezseniz çalışmayacaktır.

Firebase Cloud Messaging dersimiz çok uzun oldu fakat Push notification konusu genel olarak biraz daha zor ve uğraştırıcı bir konudur. Umarım sizlere faydası olacaktır bu dersimizin. Sorularınızı konu altından veya sorucevap.mobilhanem.com adresinden sorabilirsiniz.

Tüm Android Ders, Proje ve Kaynak Kodlar için tıklayınız.

34
Exit mobile version