Bài 72: Học Firebase Cloud Message(FCM)

Trong bài Bài 50: Cách sử dụng Google Cloud Message trong Android Tui đã hướng dẫn rất chi tiết về Google Cloud Message(GCM). Hiện nay Google đã ra phiên bản mới là Firebase Cloud Message (FCM) cực kỳ hiệu quả, vì vậy để giúp các Sinh Viên hiểu và triển khai được FCM Tui đã quay Video lại từng bước làm FCM (hơn 2 giờ xem Video). Các em có thể xem Video tại post này (Tui không đủ thời gian để làm trau chuốt cái Video, nên Tui đang để thô các bạn cứ việc xem nhé, có thể kéo qua những chỗ phải chờ lâu. Chú ý Video này hướng dẫn cách làm FCM đã chạy hoàn chỉnh ngon như cơm mẹ nấu, có một vài lần test không ra là do mạng chậm nên các em cứ coi như OK nhé).

Để học FCM các em cần biết về kiến trúc hoạt động của FCM:

b72_1

Ở hình trên Tui để 5 bước, các bạn cần hiểu kiến trúc hoạt động của FCM như sau:

Bước 1: Khi các thiết bị của khách hàng cài phần mềm của Ta vào thì nó sẽ gửi yêu cầu lên Firebase Cloud Server để xin  Token

Bước 2: Firebase Server sẽ trả về Token(không trùng nhau) cho thiết bị đó.

Bước 3: Nhiệm vụ của Ta phải lưu được Token mà Firebase trả về cho từng thiết bị để sử dụng lại lần sau. Phải xây dựng Webservice để để bắn Token này về Server riêng của ta

Bước 4: Là phần Admin để quản trị việc thông báo Push Message cho các khách hàng có sử dụng phần mềm của mình (không tốn phí, được gửi khoảng gần 1000 thiết bị), Bước này Ta phải gửi danh sách Token + Thông điệp muốn thông báo cho FireBase (Tức là ta không có trực tiếp gửi cho khách hàng được , mà phải gửi yêu cầu cho Firebase xử lý. Vì lúc này Firebase cũng đang quản lý Token)

Bước 5: Sau khi Firebase nhập được yêu cầu từ bước 4, nó sẽ tự động kiểm tra và gửi thông báo tới toàn bộ khách hàng đúng với Token mà bước 4 yêu cầu.

Trong phần hướng dẫn này, Tui yêu cầu các bạn làm theo (các bạn có thể dùng PHP):

1) Xây dựng Remote Server (Asp.net – C#, IIS Webserver)

– SQL Server

– RESTFul

– IIS Web Server

2)Tạo Project Android để có tương tác FCM

3) Sử dụng https://console.firebase.google.com

4) Test chức năng FCM

Chi tiết từng bước làm Tui trong Video này, các bạn xem ở đây (Youtube) – Khoảng hơn 2 Tiếng nhé(đang upload lại, do bị lệch khung hình với âm thanh):

[youtube https://www.youtube.com/watch?v=E1JMPpoHqHE]

Còn đây là source code:

Chúc các bạn thành công.

=================================

Nếu khó theo dõi bằng Video được thì bạn có thể theo dõi hướng dẫn bằng các giải thích dưới đây:

1) Xây dựng Remote Server (Asp.net – C#, IIS Webserver)

  • Tạo Cơ sở dữ liệu CSDLFirebase:

b72_2

hình Trên Tui tạo CSDL tên : CSDLFirebase, có 1 bảng tên là FCM với 2 cột (id-tự động tăng làm khóa chính, bạn để Identity Specification =YES ; Cột token kiểu chuỗi để lưu Token mà firebase gửi về cho từng thiết bị).

  • Viết Webservice (Restful – Web API) để Mobile tương tác được với CSDLFirebase:

Khởi động Visual Studio, tạo 1 Project đặt tên là FCMServer:

b72_3

Ở hình trên Tui chọn C#/ Web / chọn ASP.NET Application. Phần Name đặt là FCMServer rồi nhấn nút OK, lúc này Visual mở ra màn hình hỏi ta chọn Template tiếp theo, ở màn hình dưới này ta chọn Empty rồi nhấn nút OK:

b72_4

Sau khi nhấn nút OK, ta được Solution dưới đây:

b72_5

Ta tiến hành tạo thư mục Models (để tạo lớp FCM, ở đây bạn có thể dùng LinQ để tự phát sinh, nhưng đây là chủ ý của Tui, Tui muốn hướng dẫn các bạn cách dùng ADO.NET):

b72_6

Ở màn hình trên, bạn bấm chuột phải vào Project/ chọn Add/ chọn new folder, rồi đặt tên folder là Models:

b72_7

Ta cần tạo 1 lớp tên là FCM trong thư mục Models này, bằng cách: Bấm chuột phải vào Models/chọn New/ chọn Class:

b72_8

Một màn hình hiển thị lên, ta chọn Class, rồi đặt tên là FCM, nhấn Add để tạo:

b72_9

Ta tiến hành coding cho lớp FCM như sau:

b72_10

tương tự tạo 1 thư mục mới tên là Controllers:

b72_11

Bấm chuột phải vào Controllers/ chọn Add/ chọn Controller…:

b72_12

Một cửa sổ hiển thị lên, mặc định là DefaultController, bạn sửa lại thành FCMController:

b72_13Khi bạn bấm Add, ta có kết quả:

b72_14

Bạn quan sát lớp FCMController được sinh ra , kế thừa từ ApiController, đồng thời phát sinh thêm lớp WebApiConfig.cs:

b72_15

Tui có giải thích file config này ở đây (các bạn có thể đọc lại): https://duythanhcse.wordpress.com/2015/11/10/bai-69-xay-dung-web-service-dung-api-restful-servicephan-2/

Để lập trình con FCMController, trước tiên ta cần cấu hình chuỗi kết nối tới CSDL trước trong file Webconfig:

b72_16

Bạn để ý Tui bổ sung :

[code language=”xml”]

<appSettings>
<add key="strConnection" value="server=.;database=CSDLFirebase;user id=sa;pwd=@Hunggia113"/>
</appSettings>

[/code]

Tùy vào cấu hình SQL Server của bạn thì bạn cần đặt đúng user + mật khẩu nhé.

Giờ ta quay trở lại lập trình FCMController:

[code language=”csharp”]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

using System.Data;
using System.Data.SqlClient;
using FCMServer.Models;

namespace FCMServer.Controllers
{
public class FCMController : ApiController
{
///
<summary>
/// trả về FCM theo id
/// </summary>

/// <param name="id">id trong CSDL</param>
/// <returns></returns>
[HttpGet]
public FCM getFCM(int id)
{
try
{
string strConnection =
System.Configuration.ConfigurationManager.AppSettings["strConnection"];

SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
string sql = "select * from FCM where id=@id";
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.Add("@id", SqlDbType.NVarChar).Value = id;
SqlDataReader reader = command.ExecuteReader();
FCM fcm = null;
while (reader.Read())//trong khi còn dữ liệu để đọc
{
fcm = new FCM();
fcm.Id = reader.GetInt32(0);
fcm.Token = reader.GetString(1);
}
conn.Close();
return fcm;
}
catch (Exception ex)
{
throw ex;
}
}
///
<summary>
/// Hàm trả về toàn bộ FCM để ta gửi Push Message cho toàn bộ device
/// </summary>

/// <returns></returns>
[HttpGet]
public List<FCM>getFCMS()
{
try
{
List<FCM> dsFcm = new List<FCM>();
string strConnection =
System.Configuration.ConfigurationManager.AppSettings["strConnection"];

SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
string sql = "select * from FCM";
SqlCommand command = new SqlCommand(sql, conn);
SqlDataReader reader = command.ExecuteReader();
FCM fcm = null;
while (reader.Read())//trong khi còn dữ liệu để đọc
{
fcm = new FCM();
fcm.Id = reader.GetInt32(0);
fcm.Token = reader.GetString(1);
dsFcm.Add(fcm);
}
conn.Close();
return dsFcm;
}
catch (Exception ex)
{
throw ex;
}
}
///
<summary>
/// trả về FCM dựa vào 1 token
/// </summary>

/// <param name="token">token từ Firebase</param>
/// <returns>Nếu có trả về FCM, không có trả về null</returns>
[HttpGet]
public FCM getFCM(string token)
{
try
{
string strConnection =
System.Configuration.ConfigurationManager.AppSettings["strConnection"];

SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
string sql = "select * from FCM where token=@token";
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.Add("@token", SqlDbType.NVarChar).Value = token;
SqlDataReader reader = command.ExecuteReader();
FCM fcm = null;
while (reader.Read())//trong khi còn dữ liệu để đọc
{
fcm = new FCM();
fcm.Id = reader.GetInt32(0);
fcm.Token = reader.GetString(1);
}
conn.Close();
return fcm;
}
catch (Exception ex)
{
throw ex;
}
}
///
<summary>
/// Dịch vụ này dùng để lưu token của Device vào cơ sở dữ liệu
/// </summary>

/// <param name="token">token do Firebase truyền về</param>
/// <returns>lưu thành công trả về true, thất bại flase</returns>
[HttpPost]
public bool saveToken(string token)
{
try
{
if (getFCM(token) != null) return false;

string strConnection =
System.Configuration.ConfigurationManager.AppSettings["strConnection"];

SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
string sql = "insert into FCM(token) values(@token)";
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.Add("@token",SqlDbType.NVarChar).Value=token;
int kq = command.ExecuteNonQuery();//tiến hành insert
conn.Close();
return kq > 0;
}
catch(Exception ex)
{
throw ex;
}
}
}
}

[/code]

Bạn chú ý chép vào nhé, vì muốn hiểu nó bạn phải rành về Lập trình cơ sở dữ liệu với C#, tuy nhiên trong bài này ta coi như đã biết, ứng dụng vào hệ thống này cho tiện.

Tiếp theo tạo 1 thư mục Views:

b72_17

Từ thư mục Views/ nhấn chuột phải/chọn Add/ Webform:

b72_18

màn hình hiển thị lên ta đặt tên là Admin rồi nhấn OK:

b72_19

bạn thiết kế Admin.aspx như sau (mục đích của trang này là cho phép gửi Push Notification tới toàn bộ Thiết bị của khách hàng có cài phần mềm Mobile của ta):

b72_20

Dưới đây là coding HTML (Design, chép vào Source):

[code language=”html”]

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Admin.aspx.cs" Inherits="FCMServer.Views.Admin" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>

<form id="form1" runat="server">

<div>

Nhập tiêu đề muốn gửi thông báo:
<asp:TextBox ID="txtTieuDe" runat="server" Width="326px"></asp:TextBox>

Nhập nội dung muốn gửi thông báo:
<asp:TextBox ID="txtNoiDung" runat="server" Height="150px" TextMode="MultiLine" Width="358px"></asp:TextBox>

<asp:Button ID="btnGui" runat="server" OnClick="btnGui_Click" Text="Gửi thông báo tới toàn bộ khách hàng" />

kết quả sau khi gửi thông báo:
<asp:TextBox ID="txtKetQua" runat="server" Height="150px" TextMode="MultiLine" Width="358px"></asp:TextBox>

</div>

</form>

</body>
</html>

[/code]

Bên trên là phần giao diện, bây giờ ta xử lý phần Coding:

b72_21

Coding đầy đủ của màn hình trên:

[code language=”csharp”]

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace FCMServer.Views
{
public partial class Admin : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected void btnGui_Click(object sender, EventArgs e)
{
Controllers.FCMController fcmController = new Controllers.FCMController();
List<Models.FCM> dsFcm = fcmController.getFCMS();
WebRequest tRequest;
//thiết lập FCM send
tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "POST";
tRequest.UseDefaultCredentials = true;

tRequest.PreAuthenticate = true;

tRequest.Credentials = CredentialCache.DefaultNetworkCredentials;

//định dạng JSON
tRequest.ContentType = "application/json";
tRequest.Headers.Add(string.Format("Authorization: key={0}", "<Chép KEY trong Firebase của bạn>"));
tRequest.Headers.Add(string.Format("Sender: id={0}", "<Chép ID trong Firebase của bạn>"));

string[] arrRegid = dsFcm.Select(x => x.Token).ToArray();
string RegArr = string.Empty;
RegArr = string.Join("\",\"", arrRegid);

string postData = "{ \"registration_ids\": [ \"" + RegArr + "\" ],\"data\": {\"message\": \"" + txtNoiDung.Text + "\",\"body\": \"" + txtNoiDung.Text + "\",\"title\": \"" + txtTieuDe.Text + "\",\"collapse_key\":\"" + txtNoiDung.Text + "\"}}";

Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
tRequest.ContentLength = byteArray.Length;

Stream dataStream = tRequest.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

WebResponse tResponse = tRequest.GetResponse();

dataStream = tResponse.GetResponseStream();

StreamReader tReader = new StreamReader(dataStream);

String sResponseFromServer = tReader.ReadToEnd();

txtKetQua.Text = sResponseFromServer; //Lấy thông báo kết quả từ FCM server.
tReader.Close();
dataStream.Close();
tResponse.Close();
}
}
}

[/code]

Bạn để ý :

Dòng 36: <Chép KEY trong Firebase của bạn>

Dòng 37: <Chép ID trong Firebase của bạn>

==> Bạn chỉ cần sửa 2 dòng lệnh này là đủ rồi, đó chính là chỗ tạo Project trong Firebase(Sẽ hướng dẫn các bạn tạo Project Firebase và chép vào chỗ này sau, Tạo thời ta cứ cấu hình chạy IIS Webserver. Khi nào qua phần Firebase ta sẽ chép lại sau)

  • Cấu hình IIS WEB Server:

Vì Tui đã hướng dẫn rất kỹ phần cấu hình IIS WEB Server trong bài 71 https://duythanhcse.wordpress.com/2015/11/11/bai-71-xay-dung-web-service-dung-api-restful-servicephan-4/ rồi, nên các bạn tự xem lại, dưới đây tui chụp hình kết quả:

b72_22Kết quả chạy:

b72_23

Chú ý ở trên là local host, lúc tương tác Mobile nó hiểu nhầm, nên bạn phải lấy địa chỉ IP (Mở của sổ Command line, gõ ipconfig để lấy IP):

b72_24

Ở cửa sổ trên (gõ Tổ hợp phím Windows + R), ta nhập cmd rồi nhấn OK:

b72_25Gõ Ipconfig ta được địa chỉ IP như bên dưới, giờ xem website từ IIS:

b72_26Hay vào xem Admin.aspx:

b72_27==> Các Em chú ý địa chỉ IP là theo máy các em nhé, nếu đã có domain thì chả cần quan tâm cái này, Nhưng ta là lập trình viên, đang test nên phải biết vụ này. Từ Mobile sẽ tương tác dựa trên cái này.

2)Tạo Project Android để có tương tác FCM

Bây giờ cá em tiến hành tạo 1 Project Android Studio có tên FCMClient như hình chụp dưới đây:

b72_28

Em để ý Tui khoanh đỏ package nhé, nó được dùng để đăng ký trên firebase.

3) Sử dụng https://console.firebase.google.com

Các em vào trang trên, Nếu chưa có Project nào có thì có hình sau:

b72_29

Nếu đã có Project rồi, thì hệ thống liệt kê ra như dưới đây:

b72_30

Giờ em chọn Create New Project để tạo:

b72_31

Các em đặt tên Project, chọn Việt Nam rồi nhấn Create Project:

b72_32Các Em thấy Tui đánh dấu số 1, số 2. Số 1 là cấu hình Firebase vào ứng dụng Android FCMClient, số 2 là xem danh sách các Project khác (em nhấn vào số 2 sẽ thấy danh sách các Project Firebase khác).

Bây giờ các em nhấn vào số 1 (Add Firebase to your Android app):

b72_33

Ta tiến hành Copy Package bên Project Android FCMClient vào chỗ này:

b72_34

Sau khi copy xong, các em nhấn ADD App:

b72_35Em Thấy Google hướng dẫn, tại màn hình này sẽ có file google_services.json tải về, và yêu cầu ta lưu vào bên trong thư mục app:

b72_36

Hình trên em thấy Tui trỏ tới thư mục app và nhấn Save (có thể lưu sau nếu quên bước này). Sau đó nhấn Continue để tiếp tục:

b72_37

Em thấy Google hướng dẫn ta sao chép các cấu hình vào Project rồi nhấn Sync now:

Đầu tiên là chép

classpath 'com.google.gms:google-services:3.0.0'
b72_38
Bước tiếp theo là sao chép:
apply plugin: 'com.google.gms.google-services'
Đồng thời sao chép cả:
compile 'com.google.firebase:firebase-messaging:9.4.0'
b72_39Các em chép cho đúng rồi nhấn Sync Now, chỗ Thấy khoanh tròn.

Như vậy sau khi Sync Now hoàn tất, ta quay lại Console của Firebase rồi nhấn finish:

b72_37

màn hình trong console sẽ như sau:

b72_40

Các em thấy Tui khoanh đỏ góc phải bên trên của Project không, nhấn vào đó nhé:

b72_41Em chọn Manage:

 

b72_42

Em thấy màn hình trên có thông tin Project, file google-services.json để lưu lại nếu các em lúc nãy quên lưu.

Giờ em nhấn vào tab CLOUD MESSAGEING nhé:

b72_43

ở trên Tui khoanh: Server Key, Sender ID. Đây là 2 thông số quan trọng để chép vào Admin.aspx (bên trên Thầy có nói để dòng 36,37 nhớ không?

Dòng 36 chép Server Key vào

Dòng 37 chép Sender Id vào

b72_44

Em thấy đó, Mỗi 1 Project sẽ có Server Key, Sender ID khác nhau. Mỗi 1 Mobile App em nên tạo 1 Firebase app nhé. Dĩ nhiên miễn phí thì chỉ tối đa 10 app thì phải. Em nhớ chép cho đúng vào Admin.aspx của em.

  • Bây giờ ta tiến hành xây dựng Mobile App để nó có thể nhận được Token và Push Message từ Firebase:

b72_45

trước tiên ta tạo lớp đa tiến trình FireBaseIDTask để lưu token vào CSDL riêng của ta do Firebase gửi về cho từng thiết bị:

[code language=”java”]
<pre>package com.tranduythanh.fcmclient;

import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
* Created by cafe on 11/08/2016.
*/

public class FireBaseIDTask extends AsyncTask<String,Void,Boolean>
{
@Override
protected Boolean doInBackground(String… params) {
try
{
URL url=new URL("http://http://192.168.11.93/hocfcm/api/fcm/?token="+params[0]);
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type","application/xml;charset=UTF-8");
InputStream inputStream=connection.getInputStream();
InputStreamReader inputStreamReader=new InputStreamReader(inputStream,"UTF-8");
BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
StringBuilder builder=new StringBuilder();
String line=bufferedReader.readLine();
while (line!=null)
{
builder.append(line);
line=bufferedReader.readLine();
}
boolean kt=builder.toString().contains("true");
return kt;
}
catch (Exception ex)
{
Log.e("LOI",ex.toString());
}
return null;
}

@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
}
}</pre>
[/code]

Với Firebase ta phải có 2 Service để hoạt động: Serivice tự động lắng nghe Token cho từng thiết bị và Service tự động lắng nghe Push Message, cách làm như sau:

  • đầu tiên là Service tự động lắng nghe Token:

b72_46

Lớp này Thầy đặt tên là: MyFirebaseIDService kế thừa từ FirebaseInstanceIdService, chi tiết coding:

[code language=”java”]
<pre>package com.tranduythanh.fcmclient;

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

/**
* Created by cafe on 11/08/2016.
*/

public class MyFirebaseIDService extends FirebaseInstanceIdService {
@Override
public void onTokenRefresh() {
super.onTokenRefresh();
String token= FirebaseInstanceId.getInstance().getToken();
luuTokenVaoCSDLRieng(token);
}

private void luuTokenVaoCSDLRieng(String token) {
new FireBaseIDTask().execute(token);
}
}</pre>
[/code]

Các em để ý hàm onTokenRefresh thường chỉ chạy 1 lần, khi nào có sự thay đổi mới thì nó mới chạy tiếp(tự động). Nên nhiều lúc vì lý do gì đó lần đầu chạy lấy được token nhưng lại không lưu vào được CSDL riêng do ta xây dựng, nên có thể mất token của thiết bị này (Để nó chạy lại ta thường phải clear cache, clear data, uninstall ứng dụng này ra khỏi thiết bị. Nhưng chú ý máy của Khách hàng làm sao ta làm được thao tác này?). Do đó chút nữa chúng ta sẽ xử lý trường hợp này sau nhé.

  • Tiếp theo là Service tự động lắng nghe Push Message:

b72_47

Tui đặt lớp này là: MyFirebaseMessagingService kế thừa từ FirebaseMessagingService

Khi có Push Message nó sẽ tự động thông báo cho khách hàng. Chú ý rằng ở đây có 2 kênh gửi Push Message

b72_48

  • Kênh thứ 1: Gửi trực tiếp từ Console Firebase:

b72_49

Ta nhấn mục Notification mà Tui đánh dấu là số 1, nhìn góc phải bên trên Tui có đánh số 2 (New Message), Muốn gửi Push Message thì ta nhấn vào đây. Đồng thời nhìn danh sách phía bên dưới là Tui đã demo ứng dụng thành công hàng loạt các Push Message.

Khi nhấn vào New Message:

b72_50

Mục số 1: nhập nội dung thông báo

Mục số 2: Tiêu đề

Mục số 3: Nhấn vào chọn package để gửi thông báo.

Mục số 4: Nhân SEND MESSAGE

Khi nhấn SEND MESSAGE, hệ thống sẽ xử lý, và gửi thông tin tới toàn bộ các thiết bị được cung cấp token ứng với Package này.

Ngoài ra ta có thể chọn từng Token để gửi nhé (chọn Single Device)

  • Kênh thứ 2: Do Lập trình viên của ta định nghĩa, cụ thể là web: Admin.aspx mà ta đã lập trình bên trên:

b72_51

Dĩ nhiên là giờ cả 2 kênh chưa sử dụng được, vì Ta đã viết xong ứng xong FCMClient đâu.

Như vậy các em đã nắm được có 2 kênh gửi Push Message. Giờ ta tiến hành coding cho MyFirebaseMessagingService này nhé:

[code language=”java”]
<pre>package com.tranduythanh.fcmclient;

import android.app.NotificationManager;
import android.app.PendingIntent;
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;

/**
* Created by cafe on 11/08/2016.
*/

public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if(remoteMessage.getNotification()!=null)
{
hienThiThongBao(remoteMessage.getNotification().getBody());
}
hienThiThongBao(remoteMessage.getData().get("body"),remoteMessage.getData().get("title"));
}
private void hienThiThongBao(String body,String title) {
Intent intent=new Intent(this,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
Uri sound= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder=new NotificationCompat.Builder(this)
.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(sound)
.setContentIntent(pendingIntent);
NotificationManager manager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(0,builder.build());
}
private void hienThiThongBao(String body) {
hienThiThongBao(body,"google");
}
}</pre>
[/code]

Như vậy là Ta đã coding xong cả 2 Service tự động lắng nghe nhận Token và nhận Push Message. Bây giờ ta cần cấu hình 2 Serivce này trong Manifest để nó có thể tự động lắng nghe được khi Khách hàng cài app của ta:

[code language=”xml”]
<pre><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tranduythanh.fcmclient">
<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=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service android:name=".MyFirebaseIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application>

</manifest></pre>
[/code]

Để ý Manifest có cấp phép sử dụng Internet, có 2 Service lắng nghe token và push message

  • Cuối cùng ta vào lớp MainActivity để xử lý lấy token (trường hợp mà Tui nó bị cái gì đó không lưu được)

[code language=”java”]
<pre>package com.tranduythanh.fcmclient;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseMessaging.getInstance().subscribeToTopic("testfcm");
String token= FirebaseInstanceId.getInstance().getToken();
new FireBaseIDTask().execute(token);
}
}</pre>
[/code]

ở coding trên, luôn luôn chạy khi App được mở lên, đa tiến trình của ta kiểm tra nó tồn tại hay không thì lưu vào CSDL (vì như Tui giải thích là onTokenRefresh chỉ chạy 1 lần (chạy lại khi có token mới). Nên nếu vì lý do gì đó không lưu được lần đầu, thì các lần sau vẫn lưu được.

==>Bây giờ các em chạy Ứng dụng FCMCLient này vào thiết bị, thì ta lưu được Token do Firebase gửi về như hình dưới đây:

b72_52

Vào admin.aspx để gửi thông báo tới toàn bộ thiết bị mà cài đặt phần mềm của ta:

b72_53Ở trên em thấy nó báo thành công 2, thất bại 5 không… Như vậy Token nào đúng thì nó sẽ gửi được em nhé

Tới đây em có thể test gửi Message trực tiếp từ console của firebase được rồi nhé.

Khi các em test OK thì sẽ có kết quả như sau:

b72_54

Như vậy là Tui đã hướng dẫn đầy đủ và chi tiết từ A-z cách xây dựng Firebase Cloud Message(FCM) rồi nhé. Các em nhớ làm lại nhiều lần. Có source code ở đầu bài này các em có thể lấy nó tham khảo.

Chúc các em thành công.

15 thoughts on “Bài 72: Học Firebase Cloud Message(FCM)”

  1. Thầy cho em hỏi, là tại sao “FirebaseInstanceId.getInstance().getToken()” nó cứ trả về null, không lấy được token của thiết bị ạ ??

  2. Hiện tại Firebase chỉ cho phép 100 kết nối nến là bản free. Nhưng chỉ có tính năng FCM là free cho tất cả kết nối đúng không bạn

  3. Cảm ơn bài chia sẻ rất hữu ích của anh,
    Chúc anh sức khỏe và hạnh phúc và có nhiều chía sẻ hơn nữa 🙂

  4. Thầy cho em hỏi cái URL url=new URL(“http://http://192.168.11.93/hocfcm/api/fcm/?token=”+params[0]); này là như em làm app gọi api từ web cung cấp,thì em truyền theo url nào ạ. em cảm ơn Thầy!

Leave a Reply