วิธีสร้าง Cloud Messaging ด้วย Firebase API และ Deploy ขึ้น Firebase Hosting

การพัฒนา Software สมัยนี้ดูเหมือนว่าการลงทุนด้วย Infrastructure เองจะได้รับความนิยมน้อยลง เพราะ มันมีต้นทุนค่าใช้จ่ายที่สูง และมีค่าใช้จ่ายแฝงตามมาอีกในอนาคต

จริงๆแล้วคำว่า Cloud Computing นั้น ไม่ใช่เรื่องใหม่ แต่เป็นการนำเสนอ Solution ต่างหาก ที่ทำให้เหล่า Developer ต้องตาม และเรียนรู้ และนี่เอง คือ ความสนุกของการทำซอฟท์แวน์ในยุคนี้

ยุคที่ Back-endless หรือ Server-less และเปลี่ยนเป็น การบริโภค Service จาก Cloud platform ของผู้ให้บริการ ช่วยให้การพัฒนาซอฟท์แวร์นั้นรวดเร็วขึ้น

ทำความรู้จัก FCM (Firebase Cloud Messaging)

FCM ไม่ใช่เรื่องใหม่ ของทาง Google จริงๆแล้ว ในอดีต Google ได้ออกผลิตภันณ์ ที่ชื่อว่า Google Cloud Messaging (GCM)

FCM Concept

หน้าที่ของ FCM คือ ทำ Cloud Platform สำหรับ Push message อะไรสักอย่างหนึ่งหา Device ปลายทางที่กำหนด และขนาดของ Message ที่ต้องการ Push นั้น Firebase ได้กำหนด Payload ไว้ที่ 4 kb ซึ่งก็มากพอสำหรับ การ Push ต่อครั้ง

1) เริ่มต้นสร้าง Project Firebase

ในที่นี้ผมสร้าง Firebase ที่ชื่อว่า goangle-firebase

2) ทำการสร้าง Hosting

คลิก GET STARTED

ซึ่งในเครื่องคอมพิวเตอร์ของเราจำเป็นต้องลง Node.JS ให้เรียบร้อยก่อนนะครับ


3) สร้างโปรเจค Firebase Hosting ไว้ในเครื่อง

ให้ทำการเปิด terminal / cli และติดตั้ง firebase-tools command ลงในเครื่อง development ของเรา แบบ global

$ npm install -g firebase-tools

จากนั้นไป directory โปรเจคของเรา และทำการ Sign in to Google ด้วยคำสั่งนี้

$ firebase login

จะได้ผลลัพธ์ ดังนี้

ทำการ init project

อาจใช้เวลาสักพักในการดาวน์โหลด dependency ต่างๆที่จำเป็น
$ firebase init
https://firebase.google.com/docs/cli/

ใช้คำสั่ง

$ firebase serve

เพื่อทำการ start server firebase hosting จะได้ผลลัพธ์ ดังนี้

ซึ่ง browser จะเปิด http://localhost:5000/ อัตโนมัติ (ขึ้นอยู่กับ port ที่ว่างในเครื่องเรา ในขณะนั้น) และเมื่อมาถึงขั้นตอนนี้นั่นหมายความว่า เราได้รู้จัก Cloud Service ของ Firebase ตัวแรกแล้ว นั่นก็คือ Firebase Hosting

4) นำ Firebase script ฝังไว้ใน Website ของเรา

ในบทความนี้จะทำในรูปแบบ web app

ในตัวอย่างนี้จะทำตัวอย่างของ web app ให้ทำการ คลิก “Add Firebase to your web app” จากนั้นทาง Firebase จะแนะนำให้เรา copy snippet ดังข้างล่าง เพื่อนำไป embed ไว้ที่เว็ปไซต์ของเรา ในที่นี้แปะไว้ที่ index.html

<script src="https://www.gstatic.com/firebasejs/3.7.4/firebase.js"></script>
<script>
// Initialize Firebase
// TODO: Replace with your project's customized code snippet
var config = {
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
storageBucket: "<BUCKET>.appspot.com",
messagingSenderId: "<SENDER_ID>",
};
firebase.initializeApp(config);
</script>

จากนั้น Firebase แนะนำให้เราเรียกใช้ Firebase JavaScript SDK ที่ต้องการ

  • firebase-app - The core firebase client (required).
  • firebase-auth - Firebase Authentication (optional).
  • firebase-database - The Firebase Realtime Database (optional).
  • firebase-storage - Cloud Storage (optional).
  • firebase-messaging - Firebase Cloud Messaging (optional).
<script src="https://www.gstatic.com/firebasejs/3.7.4/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.7.4/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.7.4/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/3.7.4/firebase-messaging.js"></script>

ในที่นี่ให้เราใช้ firebase-app.js (ซึ่งจำเป็น) และ firebase-messaging.js ก็เพียงพอแล้วสำหรับโปรเจคนี้

อ่านเพิ่มเติมได้ที่ https://firebase.google.com/docs/web/setup

5) กำหนดให้ Browser สามารถรับ Message ได้

ทำการสร้าง manifest.json ขึ้นมา และวางในระดับเดียวกับ index.html ของเรา

{
"//": "Some browsers will use this to enable push notifications.",
"//": "It is the same for all projects, this is not your project's sender ID",
"gcm_sender_id": "103953800507"
}

อ่านเพิ่มเติมได้ที่ https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/

6) ทำการสร้าง messaging object

โดยในโปรเจคนี้ผมทำการสร้าง firebase.init.js เพื่อไว้ code ตัวนี้

// Retrieve Firebase Messaging object.
const messaging = firebase.messaging();

7) ทำการสร้างฟังก์ชันของการทำ Request Permission

messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
// TODO(developer): Retrieve an Instance ID token for use with FCM.
// ...
})
.catch(function(err) {
console.log('Unable to get permission to notify.', err);
});

โค๊ดข้างบนเป็นการร้องขอ Permission ของ Browser ผู้ใช้ให้รับ Notification ที่ร้องขอมาจาก Source ได้ ในที่นี่ คือ Firebase Cloud Messaging

ให้ทำการ สร้าง function เช่น onRequestPermission() และภายในมีโค๊ดข้างบนอยู่ข้างใน

ให้ทำการ copy โค๊ดไปไว้ที่ firebase.init.js

// Request Browser notification permission
const allowBrowserNotification = () => {
messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
// TODO(developer): Retrieve an Instance ID token for use with FCM.
// ...
})
.catch(function(err) {
console.log('Unable to get permission to notify.', err);
});
};

ที่ index.html ทำการสร้างปุ่มง่ายๆขึ้นมา

<button type="button" onclick="allowBrowserNotification();">
Allow Browser Notification
</button>

8) ทำการสร้างฟังก์ชั่น เพื่อขอรับ Token

Token คือ parameter ที่ใช้ส่งในการร้องขอไปยัง Server ในแต่ละครั้ง ซึ่ง Token มีสิทธิ์ที่จะสูญหาย หรือ ถูกเคลีย์ได้ ดังนั้น ในหัวนี้เราจะทำการสร้าง ฟังก์ชั่นเพื่อร้องขอ Token ใหม่ ก่อนทำการส่ง Request ไปยัง server เพื่อทำการ Push message

// Get Instance ID token. Initially this makes a network call, once retrieved
// subsequent calls to getToken will return from cache.
messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
sendTokenToServer(currentToken);
updateUIForPushEnabled(currentToken);
} else {
// Show permission request.
console.log('No Instance ID token available. Request permission to generate one.');
// Show permission UI.
updateUIForPushPermissionRequired();
setTokenSentToServer(false);
}
})
.catch(function(err) {
console.log('An error occurred while retrieving token. ', err);
showToken('Error retrieving Instance ID token. ', err);
setTokenSentToServer(false);
});
}

ไปที่ firebase.init.js และทำการ copy code ชุดนี้ลงไป

// Request token
const getToken = () => {
// Get Instance ID token. Initially this makes a network call, once retrieved
// subsequent calls to getToken will return from cache.
messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
prompt('Your Token', currentToken);
} else {
// Show permission request.
console.log('No Instance ID token available. Request permission to generate one.');
}
})
.catch(function(err) {
console.log('An error occurred while retrieving token. ', err);
});
};

9) ทำการสร้างฟังก์ชั่น Monitor Token ในกรณี Token มีการเปลี่ยนแปลง

// Callback fired if Instance ID token is updated.
messaging.onTokenRefresh(function() {
messaging.getToken()
.then(function(refreshedToken) {
console.log('Token refreshed.');
prompt('Your Token', refreshedToken);
})
.catch(function(err) {
console.log('Unable to retrieve refreshed token ', err);
});
});

10) จัดการ Message ในกรณีการทำงานแบบ Foreground และ Background

Message ที่ผู้ใช้จะได้รับนั้นแบ่งออกเป็นสอง Use case

  • Foreground = ผู้ใช้กำลัง active หรือ focus webpage ของเรา
  • Background = ผู้ใช้กำลังใช้งานอยู่ที่แทปอื่นของ Browser

โดยทาง Firebase SDK นั้นจะมีสิ่งที่เรียกว่า Service web worker ทำหน้าที่คอย watcher message ที่ส่งมา และจะทำ action ต่อไป เพื่อ notification ผู้ใช้ให้เรา

ให้ทำการ copy code จาก ที่นี่

และเอาไว้วางไว้ระดับ เดียวกันกับ index.html

จากนั้นเปิดไฟล์ firebase-messaging-sw.js เพื่อแก้ไข

messagingSenderId: 'sender id ของเรานะครับ'

ซึ่งสามารถดูได้จากขั้นตอนที่ 4

ไปที่ firebase.init.js และ copy โค๊ดชุดนี้ลงไป

// Handle incoming messages. Called when:
// - a message is received while the app has focus
// - the user clicks on an app notification created by a sevice worker
// `messaging.setBackgroundMessageHandler` handler.
messaging.onMessage(function(payload) {
console.log("Message received. ", payload);
// ...
});

11) Deploy project ไปที่ Firebase Hosting

$ firebase deploy
ขณะกำลัง deploy ขึ้น cloud
เมื่อ deploy เสร็จแล้ว

ลองทดสอบผลลัพธ์การ deploy ให้เข้าไปที่เวปของเรา

url เว็ปไซต์จะได้มาเมื่อ deploy เสร็จแล้ว หรือ ไปที่ firebase console

12) ทดสอบฟังก์ชั่น Get token

เมื่อคลิก Get Token จะได้ Token ซึ่งอยู่ใน dialog box

13) ทดสอบ Push Message Notification

ในหัวนี้เราจะมาทำการทดสอบยิง push notification ไปยัง Firebase cloud messaging server และกำหนด ปลายทาง (Token) เพื่อให้ ผู้ใช้คนนั้นได้รับ message

  • ให้ทำการ Get Token ที่ได้จากขั้นตอนก่อนหน้าเก็บไว้
  • ไปที่ Firebase console เพื่อเอา Server key
https://firebase.google.com/docs/cloud-messaging/server
  • ในการ push notification เราต้องกำหนด request property ดังนี้

URL

https://fcm.googleapis.com/fcm/send

METHOD

POST

AUTHORIZATION

Content-Type:application/json
Authorization:key=Server key ของเรา
Postman

BODY

{ 
"notification": {
"title": "Hey Dude!!",
"body": "Good game, well play.",
"click_action" : "https://goangle-firebase.firebaseapp.com/",
"priority": "high",
"icon": "url ของ logo"
},
"to" : "token ที่ได้มา เป็น token ของ user ที่ยินยอม notification"
}

และนี่ คือ ผลลัพธ์ที่ได้

notification message แบบ background

สรุปการใช้ Firebase Cloud Messaging API นั้น เราสามารถใช้ ผ่าน REST Client เช่น Postman เพื่อทดสอบ หรือ http://pushtry.com/ ก็ได้

ในการใช้งานจริง เราจะใช้ผ่านทาง HTTP Request, cURL หรือ การใช้ Node.JS ก็แล้วแต่สะดวกเลยครับ

บทความนี่ก็เป็นแนวทางเบื้องต้น สำหรับการพัฒนา Notification แบบ web app โดยใช้ FCM SDK ของทาง Firebase ร่วมกับ Firebase Hosting ในการเก็บฟังก์ชั่นเพื่อ generate token สำหรับการส่ง notification ครับ

เว็ปไซต์อ้างอิง