Nội dung:

  • Giới thiệu Firebase Cloud Messaging
  • Tích hợp Firebase Cloud Messaging trên ứng dụng Android
  • Chạy ứng dụng
  • Kết luận
  • Tài liệu tham khảo

I. Giới thiệu Firebase Cloud Messaging

Firebase Cloud Messaging (FCM) là một giải pháp cross-platform messaging cho phép bạn thực hiện gửi tin nhắn một cách đang tín cậy và không mất phí.

FCM là một API được sử dụng để chuyển tải thông điệp cho nhiều nền tảng như Android, iOS. Sử dụng FCM, ứng dụng có thể gửi thông báo đến người sử dụng mỗi khi có thông tin mới và điều này thật hữu ích cho những tin nhắn tiếp thị như cửa hàng thời trang thông báo đến khách hàng khi có sản phẩm mới, …

1. Firebase message types

Sử dụng FCM bạn có thể gửi ba loại thông điệp tức là Notification Message, Data Message và tin nhắn với Notification & Data Payload.

1.1 Notification Message:

Các Notification messages được xử lý bởi chính bản thân SDK. Thông thường các thông báo có chứa tiêu đề, tin nhắn, biểu tượng vv, Các tin nhắn có thể được gửi từ firebase console UI. Bằng cách gửi loại thông báo này, bạn sẽ không kiểm soát được nhiều thông báo. Thông báo sẽ được hiển thị tự động khi ứng dụng ở chế độ nền.

Để send notification message, bạn cần sử dụng notification key trong dữ liệu json. Một ví dụ về notification message được đưa ra dưới đây.

{
    "to": "e1w6hEbZn-8:APA91bEUIb2JewYCIiApsMu5JfI5Ak...",
    "notification": {
        "body": "Cool offers. Get them before expiring!",
        "title": "Flat 80% discount",
        "icon": "appicon"
    }
}
1.2 Data Message:

Data messages phải được xử lý bởi ứng dụng android. Bạn có thể thêm loại thông báo này nếu bạn muốn gửi một số dữ liệu bổ sung cùng với thông báo. Tuy nhiên, việc gửi các thông báo này qua firebase console là không thể. Bạn cần phải có một server side logic để gửi thông báo bằng cách sử dụng Firebase API. Bạn cần phải sử dụng data key khi gửi tin nhắn loại này.

Một ví dụ về data message json được đưa ra dưới đây.

{
   "to" : "e1w6hEbZn-8:APA91bEUIb2JewYCIiApsMu5JfI5Ak...",
   "data" : {
     "name" : "LG LED TV S15",
     "product_id" : "123",
     "final_price" : "2500"
   }
 }
1.3 Messages with both notification and data payload:

Một thông báo cũng có thể chứa cả notification và data payload. Khi loại tin nhắn này được gửi, nó sẽ được xử lý trong hai kịch bản tùy thuộc vào trạng thái ứng dụng (background / foreground). Đối với loại thông báo này chúng ta có thể sử dụng cả notification và data keys.

Khi ở chế độ nền - Ứng dụng nhận được thông báo trong khay thông báo và chỉ xử lý data payload khi người dùng chạm vào thông báo.

Khi ở chế độ foreground - App nhận được một đối tượng tin nhắn với cả payloads.

Một ví dụ về notification & data payload message.

{
    "to" : "e1w6hEbZn-8:APA91bEUIb2JewYCIiApsMu5JfI5Ak...",
    "notification": {
        "body": "Cool offers. Get them before expiring!",
        "title": "Flat 80% discount",
        "icon": "appicon"
    },
    "data" : {
     "name" : "LG LED TV S15",
     "product_id" : "123",
     "final_price" : "2500"
   }
}

2. Message Targeting

Trong khi gửi tin nhắn bằng cách sử dụng firebase, bạn có thể chọn đối tượng được gửi tin nhắn. Bạn có thể gửi cho một người dùng hoặc nhóm người dùng bằng cách sử dụng tên topic. bạn cũng có thể gửi cho tất cả các ứng dụng.

2.1 Sending to Single User

Khi gửi tin nhắn loại này, bạn phải có thông tin token của thiết bị. Khi thiết bị Android cài đặt app của bạn, một token sẽ được gửi đến server, bạn sẽ sử dụng token này cho mục đích gửi tin nhắn cho từng cá nhân.

{
  "to": "e1w6hEbZn-8:APA91bEUIb2JewYCIiApsMu5JfI5Ak...",
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}
2.2 Topic Messaging

Topic messaging rất hữu ích khi phân đoạn người dùng được gửi tin nhắn. Với việc này tất cả người dùng phải subscribe một chủ đề firebase. Ví dụ: Khi bạn muốn gửi tin nhắn cho tất cả người dùng tham gia vào nhóm tin tức, bạn có thể tạo một topic có tên là news và gửi thông báo cho topic news .

Định dạng yêu cầu của tin nhắn chủ đề được đưa ra dưới đây. Trong trường hợp bạn cần đề cập đến tên chủ đề.

{
  "to": "/topics/news",
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}

II. Tích hợp Firebase Cloud Messaging trên ứng dụng Android

Để viết một ứng dụng Firebase Cloud Messaging trên thiết bị Android, sử dụng FirebaseMessaging API and Android Studio 1.4 trở lên. Ứng dụng FCM yêu cầu thiết bị chạy Android 4.0 trở lên.
Trước khi đi vào phần tích hợp một Firebase Cloud Messaging trên thiết bị Android, chúng ta sẽ cài đặt Android studio và chạy ứng dụng android đầu tiên.
Các bạn có thể tham khảo ở đây: (dành cho người chưa biết về lập trình Android)
http://o7planning.org/vi/10415/huong-dan-lap-trinh-android-cho-nguoi-moi-bat-dau-hello-android
Sau khi cài đặt xong và chạy được ứng dụng Android đầu tiên, chúng ta bắt đầu cài đặt để gửi và nhận message trên ứng dụng vừa rồi.

1. Tạo Firebase project

Bây giờ tôi sẽ tạo một Project đơn giản để demo tính năng gửi và nhận message. Các bạn vào trang https://console.firebase.google.com và tạo một tài khoản firebase, sau đó login vào. Click Add Project, Tại đây ta có giao diện như bên dưới

Tiếp theo chọn nền tảng ứng dụng Android, điền vào tên package của ứng dụng android của chúng ta và Create Project.

Đến đây chúng ta download file json về và bỏ vào thư mục app của Project như hình nhé.

Trong Android Studio, thêm FCM dependency vào Project-level build.gradle (project/build.gradle):

buildscript {
  dependencies {
    // Add this line
    classpath 'com.google.gms:google-services:3.1.0'
  }
}

App-level build.gradle (project/app-module/build.gradle):

...
dependencies {
    compile 'com.google.firebase:firebase-messaging:10.0.0'
}
// Add to the bottom of the file
apply plugin: 'com.google.gms.google-services'

Cuối cùng nhấn sync now xuất hiện khi bạn thay đổi code ở menu bar phía dưới. Vậy chúng ta đã xong phần thiết lập cơ bản giữa firebase project vớ ứng dụng của chúng ta. Về thiết lập kết nối đến Firebase, Ở các android studio version mới, cũng cũng cấp Firebase Assistant để hỗ trợ các config một cách nhanh chóng, các bạn có thể tham khảo tại đây:
https://developer.android.com/studio/write/firebase.html

2. Tạo App Android demo

Create 2 class sau:
MyFirebaseInstanceIdService:

package com.phongnx.testapp;

import android.util.Log;

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

/**
 * Created by usr0102382 on 2017/05/17.
 */

public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {
    private static final String REG_TOKEN = "REG_TOKEN";

    @Override
    public void onTokenRefresh() {
        String recent_token = FirebaseInstanceId.getInstance().getToken();
        Log.d(REG_TOKEN, recent_token);

        sendRegistrationToServer(recent_token);
    }

    /**
     * Persist token to third-party servers.
     * <p>
     * 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 sendRegistrationToServer(String token) {
        // Add custom implementation, as needed.
    }
}

Create class MyFirebaseMessagingService:

package com.phongnx.testapp;

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

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

/**
 * Created by usr0102382 on 2017/05/17.
 */

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MessagingService";
    public MyFirebaseMessagingService() {
        super();
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        //Log data to Log Cat
        Log.d(TAG, "From: " + remoteMessage.getFrom());

        // Process for display message
        if(remoteMessage.getNotification() != null){
            Log.d(TAG, "Notification Message: " + remoteMessage.getNotification());
            createNotification(remoteMessage.getNotification().getTitle() ,remoteMessage.getNotification().getBody());

        }

        // Process for data message
        if(remoteMessage.getData() != null){
            Log.d(TAG, "Notification Data: " + remoteMessage.getData());
            String body = "code: " + remoteMessage.getData().get("code") + " message: " + remoteMessage.getData().get("message") + " id: " + remoteMessage.getData().get("id");
            String title = "DATA Message";
            createNotification(title, body);
        }
    }

    private void createNotification(String title, String body) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
        notificationBuilder.setContentTitle(title);
        notificationBuilder.setContentText(body);
        notificationBuilder.setAutoCancel(true);
        notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
        notificationBuilder.setContentIntent(pendingIntent);

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

Thêm config vào file AndroidManifest.xml

    <application
    ...
        <service android:name=".MyFirebaseInstanceIdService" android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>
        <service android:name=".MyFirebaseMessagingService" android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>
    ...
    </application>

III. Chạy ứng dụng

1. Gửi message thông qua giao diện Firebase console

1.1 Gửi message đến single app

Đầu tiên chúng ta chạy app để lấy token. hàm onTokenRefresh() dùng để sinh token mỗi lần chúng ta cài app, khi áp chạy lần thứ 2 trở đi, token sẽ không sinh ra nữa. Để sinh ra token mới, bạn phải gỡ cài đặt app và install lại. Trong thực tế token sinh ra sẽ gửi lên server để quản lý. trong ví dụ này, mình thực hiên lấy token ở console và dùng Firebase console để gửi message.

Copy token nhân được, bước tiếp theo là vào project trên Firebase để gửi message.
Chọn Project đã tạp trên firebase -> chọn vào App đã đăng ký -> chọn New message:

Và kết quả:

1.2 Gửi message đến toàn bộ app

Tương tự như gửi message đến single device, để gửi đến tát cả các device đang cài app của chúng ta, tại Giao diện Firebase console, chúng ta chọn mục Target là User segment và chọn packge name của app:

1.3 Gửi message đến toàn Topic

Tính năng gửi message theo Topic rất thuận tiên khi ra chỉ muốn gửi đến nhưng đối tượng cùng quan tâm đến một chủ đề nào đó, chẳng chạn như người sử dụng app chọn theo dõi chủ đề sport, vậy khi chủ đề này có những thông báo mới, chúng ta chỉ gửi cho nhưng đối tượng quan tâm đến chủ đề này, việc này sẽ không ảnh hướng đến những người khác.
Cách gửi message theo chủ để cũng có tại Firebase console, chẳng hạn ở đây tôi gán mặc định cho app tho dõi topic là New, chúng ta sẽ thêm đoạn code FirebaseMessaging.getInstance().subscribeToTopic("news"); vào hàm onCreate:

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

        // Create topic
        FirebaseMessaging.getInstance().subscribeToTopic("news");
        Log.d(TAG, "Topic: News" );
    }

2. Gửi message thông qua Firebase API

Vậy là chúng ta đã tìm hiểu 3 cách gửi message thông qua giao diện Firebase console. Trên thực tế, các message không phải lúc nào cũng chỉ có dạng văn bản, như đã đề cập ở mục các loại message, Các data message khi gửi đến app, app sẽ xử lý nhưng parameter nhận được để thực hiện một công việc nào đó. Bây giờ chúng ta tìm hiểu về cách gửi data message thông qua Firebase API như thế nào. Thay cho việc tạo một giao diện chuyện nghiệp để gửi message, việc này mất nhiều thời gian, để demo, tôi sử dụng công cụ Postman để call API của Firebase.
Đầu tiên chúng ta cần lấy Web API Key của firebase project, tạo mục Setting của ứng dụng được tạo trên firebase.

Tiếp theo setting Postman để call API của firebase để gửi masage đến app.


Và nhấn send, chúng ta có được kết quả:

Bằng việc gọi Firebase API, chúng ta có thể gửi được cả 3 loại message. chi tiết có thể xem thêm ở phần tài liệu tham khảo.

IV. Kết luận

Như vậy, đến đây chúng ta đã tìm hiểu được Khái niệm về firebase, các dịch vụ của firebase, các tiện ích v.v.. còn nhiều thứ được Firabse hỗ trợ giúp chúng ta có thể nhanh chóng phát triển ứng dụng. Kết thúc bài viết này, hy vọng các bạn có cái nhìn tổng quát về firebase, là tiền đề đi sâu nghiên cứu các dịch vụ khác mà firebase cũng cấp. Bài viết này cũng đã demo được cách thức gửi nhận message của Firebase Cloud Messaging, các loại message, đối tượng nhận message, và gửi messge thông qua API như thế nào. Hẹn gặp lại ở một chuyên đề khác của Firebase mà sắp đến mình sẽ viết, đó là Firebase Realtime Database.

V. Tài liệu tham khảo

  1. http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
  2. https://firebase.google.com/docs/cloud-messaging/
  3. https://firebase.google.com/docs/cloud-messaging/admin/send-messages
  4. https://blog.pusher.com/send-push-notifications-over-firebase-cloud-messaging-fcm-with-pushers-mobile-push-notifications-api/
  5. https://viblo.asia/hungbaby/posts/ymwGXVZ4R4p1