Tuesday 20 March 2018

Push Notification example using firebase cloud messaging in android


Push Notification example using firebase cloud messaging in android



Firebase is a mobile and web-application development platform. It helps to develop app easier. It also combines analytics, database, authentication, storage , hosting, crashing reports etc. Before release of Firebase, we used Google cloud messaging service(GCM) for notification. Google introduced about firebase cloud messaging in Google I/O 2016 and rapidly growing up users usage. FCM having a lot of amazing features for mobile app developers. Compare to GCM, FCM is much more friendly because you don’t even need to see any of the server code imvolved.  

Before going to implementation, we need to set-up project details inside firebase console. 
Step1: First login into firebase console(https://firebase.google.com/). 
Step2: Then click on Add project, a pop-up dialog will appear, you need to provide project-name and country. After that click on create project. 



After creating project, inside project overview, click on ‘Add Firebase to your android app’.



Now you need to provide your app package name and as of now not providing app-nickname and signing certificate. 



Than click on register-app. Now you will see google-services.json file, just download it. You need to add google-services.json in your app folder. 




Now open android studio. 
->Click on start a new android studio-project. 
->Provide your application-name, company domain and package-name. Here you need to provide package-name() as you given in firebase.
->Click on Finish and launch project.

After launching project, you have downloaded google-services.json file, you need to add this file to your app directory, which you can find when you open your file structure to Project. 



After that you need to add the gms dependency in your project-level build.gradle file.
classpath 'com.google.gms:google-services:3.0.0'

Then, add the corresponding plugin in your app-level build.gradle. You will also need to add a Firebase messaging dependency in this file.

compile 'com.google.firebase:firebase-core:9.2.0'
compile 'com.google.firebase:firebase-messaging:9.2.0'
apply plugin: 'com.google.gms.google-services'

If you are using google-play service in your app, keep same version as you provided for firebase. 
compile 'com.google.android.gms:play-services-location:9.2.0'
compile 'com.google.android.gms:play-services-places:9.2.0'

After adding, sync your project now. Now we will create one more activity SecondActivity.java, when any notification come, on click Notification, it will redirect to SecondActivity. 

SecondActivity.java


public class SecondActivity extends AppCompatActivity {
    @Override    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

}


activity_second.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
android:layout_width="match_parent"   
android:layout_height="match_parent"    
tools:context="com.demo.notification.SecondActivity">
    <TextView        
            android:id="@+id/textView"        
            android:layout_width="wrap_content"        
            android:layout_height="wrap_content"        
            android:text="SecondActivity"        
            app:layout_constraintLeft_toLeftOf="parent"        
            app:layout_constraintRight_toRightOf="parent"        
            tools:layout_editor_absoluteY="233dp"        
            app:layout_constraintHorizontal_bias="0.501" />

</android.support.constraint.ConstraintLayout >
MainActivity.java
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.demo.notification.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="First Activity!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</android.support.constraint.ConstraintLayout>

In the next step, we will create two service class and also need to add in manifest file. 
Add this bellow code inside manifest file.

<service
            android:name=".MyFirebaseMessagingService"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
        <service android:name=".FirebaseIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
  </service>

also add bellow permission inside manifest.xml


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

Now create the service classes:

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 com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Random;

public class MyFirebaseMessagingService extends FirebaseMessagingService {


    private static final String TAG = "FCM Service";
    private static final String NOTIFICATION_ID_EXTRA = "notificationId";
    private static final String IMAGE_URL_EXTRA = "imageUrl";
    private static final String ADMIN_CHANNEL_ID ="admin_channel";
    private NotificationManager notificationManager;


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

        // TODO: Handle FCM messages here.

        Intent notificationIntent = new Intent(this, SecondActivity.class);
        final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , notificationIntent, PendingIntent.FLAG_ONE_SHOT);
        //You should use an actual ID instead
        int notificationId = new Random().nextInt(60000);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder notificationBuilder =new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(remoteMessage.getData().get("title"))
                .setContentText(remoteMessage.getData().get("message"))
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        notificationManager.notify(notificationId, notificationBuilder.build());
    }

}



Here in above class tells that when any notification arrives, by using onMessageReceived() it will receive the notification and it will show notification on notification bar.

Next create another service class FirebaseIDService, code looks like bellow:

FirebaseIDService.java

import android.util.Log;

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


public class FirebaseIDService extends FirebaseInstanceIdService {

    private static final String TAG = "FirebaseIDService";

    @Override
    public void onTokenRefresh() {
        //super.onTokenRefresh();

        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);

        System.out.println("RefreshedToken::::"+refreshedToken);

        // TODO: Implement this method to send any registration to your app's servers.
        //sendRegistrationIDToServer(refreshedToken);
    }

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM InstanceID token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private void sendRegistrationIDToServer(String token) {
        // Add custom implementation, as needed.
    }
}


By using this class, it will generate token-id which will send to server for server-side communication. 
That's it. Our code is ready to execute. Before going to test, one more thing we need do one more thing which is very interesting fact. 
If you don't have any server as of now to test your app, firebase having this facility to check your push notification using post method. If did't have google chrome postman plugin , please install it. 
The base url is : 
https://fcm.googleapis.com/fcm/send 
But to check this, you need server-key. You can find this inside firebase console of your project. After logged in into your account, click on your project, then click on project settings, inside project settings->click on cloud messaging. You will see server key, you need to copy it, it will needed in authorization as key={server-key}.



You need to provide custom body and header for post man. Also you need to add param key 'to', here to value you need to provide tokenID which will be generated in FirebaseIDService.java class.  Providing you all screen shots to help you better understand:








Message write inside your body:
{
  "to":
    "esn_3fn0jw0:APA91bFG8MLMfPFgX6GMordpl6uyr4T2lTxNB0qlMkdRB7RX17diNwnOGa3oCvrzTQ1SyovEEB8w2mjV-Pv80LHP_1ClcN8aq4D3zARum2WG0BN3D9YcQtFPFm0tsnuaJ42zfnwtatnbs0wwxVckPIYHTi3_p-l1EQ",
  "data": {
    "title": "Testing Notification",
    "message": "Hello My Message"
  }

}


Your manifest file:

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

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

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

        <service            
                android:name=".MyFirebaseMessagingService"            
                android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>
        <service android:name=".FirebaseIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>

        <activity android:name=".SecondActivity"></activity>

    </application>

</manifest>

Now Everything is ready, Run your app and click on post, you will get notification. 
Result: 



In above see notification. After clicking on notification, SecondActivity will load as bellow.










Thursday 15 March 2018

Design Pattern in Android -- Builder Pattern

Builder Pattern for Android

Builder pattern are very help-full when having model class, inside this model class having constructor with many parameters, which having some of them optional and some of them mandatory, by using builder-pattern, we will create chain of methods. The builder pattern is a good choice when designing classes whose constructors or static factories would have more than a hand-full parameters.  

For example, if you observe in our in-build alert dialog,  AlertDialog using builder class to build alert. Code is look like:

new AlertDialog.Builder(this)
        .setTitle("Alert Dialog")
        .setMessage("Alert message")
        .setCancelable(false)
        .create();


So our question will be when and why we will use builder pattern?

Assume we have a model class which having list of constructors like bellow:

Student(int id, String name){...........}
Student(int id, String name,String stream){...........}
Student(int id, String name,String stream,String historyMarks){...........}
Student(int id, String name,String stream,String historyMarks,String mathMarks){...........}
..
...
.....
.......
...........

The problem is with this once constructors are 5 or 6 long parameters long, it's really very difficult to remember every-time particular constructor we should use. The better solution is to use builder-pattern.

Now we will create a builder class for better understanding. Firstly create a model class with name BuilderPatternModel.
   
Inside this model class, we will define some variables as bellow:

private String firstName;
private String lastName;
private int age;
private String phone;
private String address;


Now we will not generate any getter and setter methods, we will create UserBuilder class inside BuilderPatternModel which is static. UserBuilder have the methods to build our object. 

For example:
public static class UserBuilder{
private String fName;
private String lName;
private int ag;
private String ph;
private String addr;
    public UserBuilder fName(String fName){
    this.fName = fName;
    return this;
}
public BuilderPatternModel build() {

    BuilderPatternModel bModel = new BuilderPatternModel(this);
    return bModel;
}
}


In this above example, having setter type method but having UserBuilder return type and at last having build() which returns BuilderPatternModel. 

Now next important thing is:
Create a private constructor BuilderPatternModel look like bellow: 

private BuilderPatternModel(UserBuilder ub){
    this.firstName = ub.fName;
    this.lastName = ub.lName;
    this.age = ub.ag;
    this.phone = ub.ph;
    this.address = ub.addr;
}

This constructor setting value and making it private so it can't access from out side.

BuilderPatternModel class looking like bellow:

public class BuilderPatternModel {

    private String firstName;
    private String lastName;
    private int age;
    private String phone;
    private String address;


    private BuilderPatternModel(UserBuilder ub){
        this.firstName = ub.fName;
        this.lastName = ub.lName;
        this.age = ub.ag;
        this.phone = ub.ph;
        this.address = ub.addr;
    }

    public String getFirstName(){
        return firstName;
    }

    public String getLastName(){
        return lastName;
    }

    public int getAge(){
        return age;
    }

    public String getPhone(){
        return phone;
    }

    public String getAddress(){
        return address;
    }


    public static class UserBuilder {
        private String fName;
        private String lName;
        private int ag;
        private String ph;
        private String addr;


        public UserBuilder() {
        }

        public UserBuilder fName(String fName){
            this.fName = fName;
            return this;
        }

        public UserBuilder lName(String lName){
            this.lName = lName;
            return this;
        }

        public UserBuilder ag(int ag){
            this.ag = ag;
            return this;
        }

        public UserBuilder ph(String ph){
            this.ph = ph;
            return this;
        }

        public UserBuilder address(String address){
            this.addr = address;
            return this;
        }

        public BuilderPatternModel build() {

            BuilderPatternModel bModel = new BuilderPatternModel(this);
            return bModel;
        }

    }//End of User-Builder
}

How to use this model class for builder-pattern:

ArrayList<BuilderPatternModel> listModel = new ArrayList<>();
BuilderPatternModel m1 = new BuilderPatternModel.UserBuilder()
        .fName("Fname1")
        .lName("lName")
        .ag(10)
        .ph("123456")
        .address("addresss")
        .build();
BuilderPatternModel m2 = new BuilderPatternModel.UserBuilder()
        .fName("Fname2")
        .address("addresss")
        .build();
listModel.add(m1);
listModel.add(m2);

How you can get the value:

for (int i = 0; i < listModel.size(); i++) {
Toast.makeText(getApplicationContext(), listModel.get(i).getFirstName() + " \n" + listModel.get(i).getLastName()
+ " \n" + listModel.get(i).getAge() + " \n" + listModel.get(i).getPhone() + " \n" + listModel.get(i).getAddress(), Toast.LENGTH_SHORT).show();

}