FCM - Firebase cloud messanfing for Notification

This post will cover step by step how to send a push notification from Firebase console to an app.

What is push notification?
Before digging into the details how to send notification in Android, it is useful to clarify what is a push notification. Using Android push notification, our app can notify a user of new events. This happens even if our app is not working in foreground. Using this service, we can send data from our server to our app whenever a new event occurs. This paradigm is much more efficient respect to keep on connecting to the server (pull method) to ask if there are new events.

Using push notification, we can keep the user informed about events without draining the smartphone battery. When a user receives the notification, it appears, as a customized icon, in the status bar. There are different paradigm to use when sending a push notification:


  1.  Message to a single device
  2.  Message to a topic (send the same message to the multiple devices subscribed to a specific topic. This implements the model publisher/subscribers)
  3.  Message to a group (multiple devices that share the same key used to identify a smartphone)


It is time to start! Create an account to access to Firebase console and define a project:


Next step is :


 Once you have created your project, you have to add the package name of your app. Be aware using the same package name in Android Studio and in the Firebase console:
keytool -exportcert -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore


At the end of this process, your project is configured on Firebase and you are ready to develop your Android app. At the end, you get a json file that you have to copy at app module level.



How to implement Android push notification with Firebase

Now we can develop the Android app integrated with Firebase. As a first step, we have to add Firebase to our app and modify gradle files. At the project level let’s modify gradle fille as:


// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.0.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
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"

    defaultConfig {
        applicationId "com.example.fcmdemo"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.0'
    compile 'com.google.firebase:firebase-messaging:9.4.0'
}
apply plugin: 'com.google.gms.google-services'


Notice we used FirebaseInstanceId singleton to the get the current instance and then the current token. It may take a while before the token is generated, so you could get a null value at the beginning.

Moreover, we can monitor the token creation process and get notified when it is available using a custom service that extends FirebaseInstanceIdService. In this case we override the onTokenRefresh method.


package com.example.fcmdemo;

import android.util.Log;

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

/**
 * Created by maitri on 16/9/16.
 */
public class FireIDService extends FirebaseInstanceIdService {
    @Override
    public void onTokenRefresh() {
        String tkn = FirebaseInstanceId.getInstance().getToken();
        Log.d("Not","Token ["+tkn+"]");

    }
}




package com.example.fcmdemo;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import org.json.JSONObject;

/**
 * Created by maitri on 16/9/16.
 */
public class FireMsgService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        Log.d("Msg", "Message data received ["+remoteMessage.getData().toString()+"]");
        Log.d("Msg", "Message body received ["+remoteMessage.getNotification().getBody().toString()+"]");
        Log.d("Msg", "Message Title received ["+remoteMessage.getNotification().getTitle().toString()+"]");

        // Create Notification
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 1410,
                intent, PendingIntent.FLAG_ONE_SHOT);

        NotificationCompat.Builder notificationBuilder = new
                NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(remoteMessage.getNotification().getBody().toString())
                .setContentText(remoteMessage.getNotification().getTitle().toString())
                .setAutoCancel(true)
                .setContentIntent(pendingIntent);

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

        notificationManager.notify((int) SystemClock.currentThreadTimeMillis(), notificationBuilder.build());
    }
}




In this case, we added messaging dependency. Once the gradle files are configured, the next step is creating our app. In the FCMActivity (Main Activity) we add a Button to get the current token. This token is important because we use it in the Firebase console, to set the right destination device.
Let us suppose, we have already defined the layout containing the button, in the Activity class:

package com.example.fcmdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.google.firebase.iid.FirebaseInstanceId;

public class FCMActivity extends AppCompatActivity {

    TextView tvToken;

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

        tvToken = (TextView) findViewById(R.id.tvToken);

        tvToken.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String tkn = FirebaseInstanceId.getInstance().getToken();
                Toast.makeText(FCMActivity.this, "Current token ["+tkn+"]",
                        Toast.LENGTH_LONG).show();
                Log.d("App", "Token ["+tkn+"]");
            }
        });
    }



}



In this method, we just log the token, but it could be used in a real app to send the token to the server so that the serve stores it.
Reminder : Don’t forget to declare this service in the Manifest.xml.

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

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

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

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

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

</manifest>
And the best thing is you can test the notification in firebase console.. just like below:
Test and send your first push notification!
To see if the setup works, run a test by sending a test message to your own mobile.

Write down your message and choose an app. Click "SEND MESSAGE".



Possible problems

  1. Compilation problems can be related to wrong version numbers in your build.gradle files.
  2. If you see a message like "com.google.firebase.crash.FirebaseCrash is not linked. Skipping initialization." in your Android Monitor log, it is ok because we don't use this Firebase Crash Analytics service.
  3. Firebase initialization is not starting
We are done!
Now you have the basic idea on how to send push notifications on Android with Firebase. Good luck! Reference https://firebase.google.com/docs/notifications/

#Share&Learn

Comments

  1. Sands Casino Resort | Tournaments and Games
    All the details about this casino & entertainment destination in Las Vegas, NV. Enjoy the best games 샌즈 카지노 쇼미 더벳 and entertainment at Sands Casino Resort - a premier entertainment

    ReplyDelete

Post a Comment

Popular posts from this blog

Read sms automatically to verify OTP

Create shapes online - Android Shapes Generator