ลองเล่น Firebase Cloud Messaging (FCM) กับ iOS

Kittisak Phetrungnapha
iTopStory
Published in
7 min readJul 11, 2016

Firebase Cloud Messaging หรือ FCM มันคืออะไร?

FCM เป็นบริการส่งข้อความแจ้งเตือนแบบ ข้ามแพลตฟอร์ม (cross-platform messaging) ทั้ง Android, iOS และ Web และเป็นหนึ่งในบริการที่ถูกรวมอยู่ใน Firebase ของ Google ที่เพิ่งเปิดตัวไปเมื่อ Google I/O 2016 ที่ผ่านมา โดยสามารถใช้งานได้ฟรี ชื่อเดิมก็คือ Google Cloud Messaging (GCM) (ถ้ายังนึกไม่ออกก็ให้ นึกถึงบริการส่งข้อความแจ้งเตือนของบริษัทยักษ์ใหญ่แห่งหนึ่งที่กำลังจะปิดตัวในเดือนมกราคม ปี 2017 TT)

แนะนำการทำงาน Firebase Cloud Messaging (FCM)

โดยเนื้อหาของ FCM ในบทความนี้จะแบ่งออกเป็น 3 ส่วน ดังนี้

  1. การตั้งค่า Firebase และ FCM เข้ากับ iOS
  2. การพัฒนาในส่วนของ iOS
  3. การใช้งาน Firebase Console สำหรับส่ง notification ให้ iOS

ถ้าพร้อมแล้วก็มาเริ่มที่ส่วนแรกกันเลย เอ่อ ลืมบอกไป เราจะใช้ภาษา Swift เป็นหลักในการพัฒนานะครับ แต่เจ้าตัว Firebase และ FCM ก็รองรับภาษา Objective-C ด้วยอยู่แล้ว ไม่มีปัญหา

การตั้งค่า Firebase และ FCM เข้ากับ iOS

สำหรับวิธีการติดตั้ง Firebase เข้ากับ iOS ให้อ่านได้ที่บทความนี้

หลังจากสร้างโปรเจค iOS และติดตั้ง Firebase เรียบร้อยแล้ว ให้เปิด .xcworkspace ขึ้นมา แล้วเปิด Podfile เพื่อทำการเพิ่ม FCM SDK ลงไป และสุดท้ายสั่ง pod install ใน terminal ก็เรียบร้อยแล้วสำหรับส่วนแรก

pod ‘Firebase/Messaging’

การพัฒนาในส่วนของ iOS

Concept คร่าวๆ ก็คือ iOS app ของเราจะทำการ register remote notifications ไปที่ Apple หลังจากนั้นเมื่อ Apple ส่ง APNs token กลับมาให้ เราก็จะทำการส่งมันไป mapping ที่ FCM ต่อ และเมื่อ token ถูก map เรียบร้อยแล้ว เจ้า FCM ก็จะทำการส่ง FCM registration token กลับมาให้ app เราอีกที ซึ่งเราสามารถเก็บเจ้า token อันนี้ไว้ใช้ตามแต่สะดวกครับ ส่วนเวลาเราจะส่ง notification เข้ามาที่ iOS app ของเรา เบื้องต้นจะใช้ Firebase Console ในการส่งครับ

AppDelegate.swift

ก่อนอื่นขออธิบายการทำงานของแต่ละ method ดังนี้ครับ

  1. didFinishLaunchingWithOptions จะถูกทำงานทันทีที่เปิด app มา โดยจะทำการ register remote notifications และสร้าง observer สำหรับดักจับค่าของ FCM registration token ไว้เลย
  2. didRegisterForRemoteNotificationsWithDeviceToken ถูกเรียกใช้งานทันทีที่ได้รับ APNs token มาจาก Apple และทำการส่งมันไปเก็บยัง FCM (ส่งให้ถูก type ด้วยนะครับ dev = .Sandbox ส่วน pro = .Prod มิเช่นนั้นจะไม่ได้รับ notification เลย)
  3. didReceiveRemoteNotification:fetchCompletionHandler เป็นตัว observer notification ที่ถูกส่งมาจาก FCM โดยจะต้องมีการบอกให้ FCM ทราบด้วยนะว่า iOS app ได้รับ notification แล้ว ด้วยบรรทัดนี้
FIRMessaging.messaging().appDidReceiveMessage(userInfo)

เพื่อให้ FCM สามารถ analyzes user ได้ว่ามีการเปิดอ่าน notification หรือไม่ เพื่อประโยชน์ในการนำข้อมูลไปวิเคราะห์ต่อ

4. tokenRefreshNotification เป็น observer method สำหรับตรวจสอบค่า FCM registration token ซึ่งถูก observed ไว้แล้วในข้อ 1 โดยถ้า token ที่ได้รับกลับมาจาก FCM ไม่เป็น nil (null ในภาษาอื่นๆ) ก็จะทำการ subscribe ไปที่ topic ชื่อว่า coffee เพื่อเอาไว้ทดสอบส่ง notification ผ่าน Firebase Console ต่อไป พร้อมกันนั้นก็จะเชื่อมต่อไปยัง FCM Server ทันที (พอดีผมติดกาแฟ (*-*) )

5. connectToFCM เป็น method สำหรับเชื่อมต่อกับ FCM Server

6. applicationDidBecomeActive มีไว้สำหรับ connect FCM Server ทันทีที่ user กลับมาเปิด app เรา และเช่นกัน applicationDidEnterBackground ก็มีไว้สำหรับ disconnect FCM ทันทีที่ user เลิกใช้งาน app เรา

สำหรับส่วนของ code ก็มีประมาณนี้ แต่เดี๋ยวก่อน… ถ้าคุณโทรมาภายใน 10 นาทีนี้ (ไม่ใช่ละ) จะบอกว่าเรายังต้องทำอีกสองอย่างที่เกี่ยวข้องกับ iOS คือ ตั้งค่าให้ app เราสามารถรับ notification แบบ background ได้ ให้ไปที่ Capabilities แล้วเปิด Background Modes พร้อมกับติ๊กเลือก Remote notifications ไปโดยพลัน

และสุดท้าย จริงๆ แล้ว เราไม่จำเป็นต้อง override method didRegisterForRemoteNotificationsWithDeviceToken เพื่อส่ง APNs token ไป map กับ FCM registration token ก็ได้ เพราะ FCM มันได้แอบทำให้เราอยู่แล้ว (ร้ายจริงๆ) แต่ที่อยากให้ override แล้วส่ง manual ไปเอง ก็เผื่อว่าเราอาจจะอยากเขียน logic อะไรสักอย่าง หลังจากได้ APNs token มานั่นเอง

ให้เราไปที่ Info.plist แล้วเพิ่ม key FirebaseAppDelegateProxyEnabled ลงไป โดยเลือก type เป็น Boolean แล้ว set NO ให้มันไปซะ เป็นอันจบ

Info.plist

จบแล้วครับ สำหรับฝั่ง iOS เป็นไง ไม่ยากเลยใช่ไหมครับ

การใช้งาน Firebase Console สำหรับส่ง notification ให้ iOS

เอาละ ต่อไปก็ถึงเวลาทดสอบ iOS app ของเรา โดยการส่ง notification ผ่าน Firebase Console กันแล้ว แต่ก่อนที่เราจะทดสอบได้นั้น เราจำเป็นต้องมีสองสิ่งนี้เสียก่อน

  1. Physical iOS device เนื่องจากตัว Simulator บน Xcode ไม่รองรับ notification
  2. Provisioning APNs SSL Certificates เป็นที่ทราบกันดีว่าเราจำเป็นต้องสร้าง push notification certificate ให้กับ iOS app ของเรา ถึงจะสามารถรับ notification ได้ ซึ่งขั้นตอนก็ค่อนข้างยุ่งยากเลยทีเดียว (ถ้าไม่ยากก็ไม่ใช่ Apple สิ) ดูรายละเอียดได้ที่

หลังจากเตรียมสองข้อด้านบนเรียบร้อยแล้วก้เปิด Firebase Console ได้เลย!!!

เมื่อเปิดมาแล้ว ก่อนอื่นให้เรา upload Provisioning APNs SSL Certificates ที่ได้จากข้อสองด้านบนให้กับ Firebase เสียก่อน ให้กดที่รูปเฟืองตรงชื่อโปรเจคของเรา แล้วเลือก Project settings

หลังจากนั้นให้เลือกที่แท็บ Cloud Messaging

จะเห็นว่ามีให้ upload certificate สองช่อง คือ development กับ production ให้เรากด upload development ก่อน (ตอนเอาขึ้น App Store อย่าลืมกลับมาทำด้วยละ) เมื่อกดแล้วจะขึ้น pop up ให้ browse ไฟล์ .p12 เข้าไป (ย้ำว่า .p12) พร้อมกับให้ใส่รหัสผ่านตอน export .p12 ไฟล์นี้ออกมาจาก Keychain Access ด้วย แต่ถ้าใคร export แบบไม่ใส่รหัสก็ปล่อยว่างไว้ได้เลยครับ (เหมือนผม 555) แล้วก็กด upload โล้ดด

เป็นอันเสร็จพิธีสำหรับการเพิ่ม Provisioning APNs SSL Certificates จะเห็นว่าไฟล์ .p12 ของเราได้ถูกเพิ่มเข้าไปแล้ว โดยสามารถมากด download ตอนไหนก็ได้ รวมถึง upload ไฟล์ใหม่ได้ด้วย ผ่านปุ่มจุดสามจุด (ไม่รู้ว่ามันเรียกว่าอะไร ขี้เกียจไป search อากู๋ละ)

ต่อมาเราจะทดลองส่ง notification กัน (จริงๆ ล่ะ) โดยให้เรากดไปที่เมนูซ้ายมือของ Firebase Console ที่ชื่อว่า Notification

แล้วจะพบกับหน้าประวัติการส่ง notification ที่ผ่านมา ให้เรากดที่ปุ่ม New Message ส่วนถ้าใครยังไม่เคยส่งมาก่อน ก็จะยังไม่มีอะไรขึ้น ให้เรากดที่ปุ่ม Send your first message แทน

หน้าประวัติการส่ง notification

จากนั้นจะขึ้นหน้าต่างให้เรากรอกรายละเอียดของ notification ที่จะส่งออกไป ประมาณนี้ เดี๋ยวจะอธิบายแต่ละส่วนให้ฟังครับผม

  • Message text เป็น title ของ notification
  • Message label (optional) อันนี้ลองใส่ไปแล้ว ไม่เห็นมันจะมีอะไรเกิดขึ้น ผมเลยไม่ใส่มันละ (-*-)
  • Delivery date เราสามารถกำหนดได้ว่าจะให้ส่ง notification แบบไหน ระหว่างส่งทันที หรือจะตั้งเวลาส่งก็ได้ (อันนี้ชอบมากๆ เอาไปทำ campaign ได้อีกเยอะเลย)
สามารถตั้งเวลาส่ง notification ได้
  • Target คือ เป้าหมายที่เราต้องการส่ง notification ไปหา สามารถแบ่งย่อยได้อีก 3 แบบ ดังนี้

User segment โดยเราสามารถส่ง notification โดยเลือกจาก app หรือ Bundle ID ได้ นอกจากนี้ยังสามารถ filter เงื่อนไขเพิ่มได้ด้วยถ้าต้องการ เช่น Audience, Language, Version เป็นต้น อารมณ์เหมือนเรา broadcast message หา user ทุกคนที่ติดตั้ง app ของเราอยู่นั่นเอง

เลือก target จาก User segment

Topic วิธีนี้เราสามารถเลือกส่ง notification ให้กับ user บางกลุ่มภายใน app เดียวกันได้ ยกตัวอย่างให้เห็นภาพ เช่น ผมทำ app เกี่ยวกับ life style โดยมีเมนูหนึ่งให้ user subscribe เข้ามาที่ life style ที่สนใจ แล้วทาง app จะส่งบทความที่น่าสนใจเกี่ยวกับหัวข้อนั้นๆ ไปให้ สมมุติผมเป็นคนชอบกินกาแฟ (เรื่องจริงนั่นแหละ) ผมก็ subscribe เรื่องเกี่ยวกับกาแฟไว้ ทีนี้ผมก็จะได้รับ notification เกี่ยวกับกาแฟนั่นเอง เป็นต้น ซึ่งการจะ subscribe topic ได้นั้น ต้องให้ทาง iOS app subscribe เข้ามาด้วย code นี้ (ผมแอบใส่ไว้ตั้งนานแล้ว)

FIRMessaging.messaging().subscribeToTopic(“/topics/coffee”)

หลังจาก iOS app subscribe มาแล้ว ในกรณีที่ยังไม่เคยมี topic นี้มาก่อน อาจจะต้องรอประมาณ 3–6 ชั่วโมง ก็จะมี topic เพิ่มเข้ามาใน Firebase Console ให้เลือกส่ง notification ได้

Coffee’s topic

Single device อันนี้ก็ตรงๆ เลย ส่งได้ทีละ 1 เครื่องเท่านั้น ตาม FCM registration token ที่กรอกเข้าไป

Single device
  • Advanced options สามารถระบุค่าใน field ต่างๆ เพิ่มได้ ดังนี้
การระบุค่าต่างๆ ใน Advanced options

Title สิ่งที่ระบุเข้าไป จะถูกนำมาแทนที่ชื่อ app ของเรา เวลา notification วิ่งเข้ามาใน notification tray ของ iOS

Custom data ไว้สำหรับส่งค่าเฉพาะ ที่ต้องการได้ เช่น ส่งค่า screen_name ไป เวลา user เปิดอ่าน notification ก็สามารถเขียน code เช็คได้จากฝั่ง iOS ว่าจะให้ไปเปิดหน้าไหนภายใน app เป็นต้น โดย custom data จะส่งเป็น key-value ตามปกติ

Priority ค่านี้ค่อนข้างสำคัญมากๆ โดยจะมีให้เลือกระหว่าง Normal กับ High ซึ่งจากการทดสอบ ถ้าเลือก Normal ไว้ แล้วในกรณีที่ user ปัด app เราทิ้งจาก multi tasks เราจะไม่ได้รับ notification จาก FCM เลย เพราะฉะนั้นเลือก High ไว้ก่อน

Sound เอาเสียงไหม เวลา notification เข้ามาที่ iOS app

iOS badge เมื่อ notification วิ่งเข้ามาที่ iOS เราต้องการให้ badge แสดงที่ app icon ของเราด้วยไหม ถ้าต้องการก็เลือกจำนวน badge ต่อได้เลย

Expires ในกรณีที่ตอน FCM ส่ง notification มาที่ iOS app ของเรา แล้วเกิดตอนนั้นเครื่องเราแบตหมด หรือ internet มีปัญหาพอดี ทำให้เราไม่ได้รับ notification แต่ notification นั้นจะยังค้างรอการส่งอยู่ภายในระบบจนกว่าจะ expires โดยตั้งระยะเวลา expires ได้สูงสุด 1 เดือน

โอเค กรอกค่าต่างๆ ให้พร้อม แล้วกดปุ่ม Send Message กัน แล้วจะขึ้นหน้าต่างให้กด Send อีก อย่ารอช้า กดเลย

หน้า confirm การส่ง notification

นับหนึ่งถึงห้า ถ้าไม่มีอะไรผิดพลาด iOS app ของเราควรจะได้รับ notification เข้ามาแล้ว (รองรับภาษาไทยด้วยนะเออ)

lock screen
notification tray

พอเรากดเปิด notification แล้ว method didReceiveRemoteNotification:fetchCompletionHandler ก็จะถูกทำงาน ซึ่งเราจะทำอะไรก็ขึ้นอยู่กับ app นั้นๆ แล้ว เช่น เปิดหน้ารายละเอียดที่เกี่ยวข้องกับ notification ที่ส่งมา เป็นต้น

ตัวอย่าง log ที่ print ออกมาเมื่อ user กดเปิด notification

ภาพด้านบน คือ ข้อมูลที่ถูกส่งมาจาก Firebase Console ซึ่งอยู่ในรูปแบบ [NSObject : AnyObject] โดยจะสังเกตเห็นว่ามี custom data ที่เราใส่ไว้ตอนที่กำลังจะส่ง notification คือ screen => coffee_detail กับ coffee_id => 1 ซึ่งเราสามารถไปดึงค่านั้นๆ แล้วให้ไปทำอะไรก็ได้ตามแต่เราต้องการครับ

นอกจากนั้นหลังจากเราส่ง notification ผ่านจาก Firebase Console ได้แล้ว record ที่เราส่งก็จะมาแสดงอยู่ในหน้าประวัติการส่ง เราสามารถคลิกดูรายละเอียดได้ ซึ่งจะมีข้อมูลบอกเราด้วยว่า sent ไปเท่าไหร่ ถูกเปิดอ่านเท่าไหร่ครับ (สุดยอดเลยอันนี้)

แสดงรายละเอียดของ notification ใดๆ ที่ส่งออกไป

เป็นอันจบเป็นที่เรียบร้อยกับส่วนของการใช้งาน Firebase Console สำหรับส่ง notification ให้ iOS ครับ

เพิ่มเติม

Firebase Cloud Messaging ไม่จำเป็นต้องใช้ Firebase Console ในการส่ง notification หา iOS app เสมอไปนะครับ เพราะว่าเจ้า FCM เนี่ย มันมี API ให้เรียกใช้งานได้ด้วย ซึ่งเราสามารถพัฒนาในส่วนของ Web Server ขึ้นมา เชื่อมต่อกับ API ของ FCM แล้วให้ iOS app ของเราเรียกหา Web Server ของเราแทน เช่น เราทำ app แชทขึ้นมาสักอัน เวลาเราส่งข้อความหาเพื่อน เราก็เรียกไปที่ API สักตัวบน Web Server ของเรา Web Server ก็จะทำการเชื่อมต่อกับ FCM จากนั้น FCM จะส่ง notification หาเพื่อนที่แชทอยู่ด้วยเพื่อให้เขารู้ว่า มีข้อความใหม่เข้ามาแล้วนะ เปิด app มาแชทกะตรูเดียวนี้ เป็นต้น ซึ่งการทำลักษณะแบบนี้ จำเป็นต้องอาศัย API ของ FCM ช่วยครับ

ตัวอย่างการพัฒนาในส่วนของ Web Server ดูได้จากบทความนี้ครับ เจ้าของบทความได้เขียนเกี่ยวกับวิธีการใช้งาน FCM ใน Android ซึ่งใน part ที่สาม มีเนื้อหาของการพัฒนาในส่วนของ Web Server ด้วย ลองศึกษากันดูครับ

และสำหรับคนที่ต้องการจะ import APNs token ทั้งหมดจากระบบอื่นๆ มาที่ FCM ก็สามารถทำได้เช่นกันครับ โดย FCM จะ mapping APNs token ให้ แล้วได้ FCM registration token ออกมาครับ โดยการใช้ API ของ Instance ID อ่านรายละเอียดได้ที่

อ่านรายละเอียดแบบจัดเต็มของ Firebase Cloud Messaging ได้ที่

ทิ้งท้าย

Software ของเราจะดึงดูดให้ User ใช้หรือไม่ สิ่งแรกที่เขาได้สัมผัสก็คงจะเป็นอะไรไปไม่ได้นอกจากหน้าตาและความยากง่ายในการใช้งาน หรือเรียกง่ายๆ ว่า UI/UX ซึ่งถ้าได้ขึ้นชื่อว่าเป็น Front-End Developer แล้ว การจะทำ UI ให้ออกมาน่าสนใจ หรือทำ UX ให้ออกมาง่ายต่อการใช้งาน ไม่ซับซ้อน ทุกคนรู้ดี ว่ามันจำเป็นต้องใช้เวลามาก ดังนั้นจะดีกว่าไหม ถ้าเราเลือกทุ่มเทเวลาที่มีจำกัดของเราไปกับสิ่งเหล่านี้ ส่วนอะไรที่เราไม่ถนัด หรือที่จริงก็สามารถทำได้ แต่ก็ต้องเสียเวลามากขึ้นไปอีก เราก็หันมาใช้ตัวช่วยที่มีประสิทธิภาพสูง ช่วยลดระยะเวลาในทำงานของเราลง หรือเพิ่มเวลาให้เราสามารถเอาไปทำอย่างอื่นได้มากขึ้น แถมเรายังได้ Software ที่มีคุณภาพสูงอีกด้วย ซึ่ง ณ นาทีนี้ หนึ่งในตัวช่วยที่ว่า คงเป็นอะไรไปไม่ได้นอกจาก Firebase Cloud Messaging (FCM) นั่นเอง

ทางผู้เขียนก็หวังว่า บทความ FCM นี้ จะเป็นประโยชน์ให้กับ iOS Dev ทุกท่านที่ต้องการพัฒนาระบบ Push notification ขึ้นมาใช้งานด้วยตนเองอย่างง่ายๆ นะครับ หากมีข้อผิดพลาดประการใด ทางผู้เขียนก็ต้องขออภัยมา ณ ที่นี้ด้วยครับ สำหรับวันนี้ ลากันไปก่อน พบกันใหม่บทความหน้าครับ สวัสดีครับ

ติดตามเรื่องราวต่างๆ ทั้งเทคโนโลยี มุมมองชีวิต การเรียนรู้ การใช้ชีวิต ได้ที่ https://www.facebook.com/itopstory/

--

--

Kittisak Phetrungnapha
iTopStory

I am a software engineer who fall in love to code, read, and write. :) itopstory.com