| เลือกแพลตฟอร์ม: | iOS+ Android เว็บ Flutter Unity C++ |
ระบบจะจัดการข้อความขาเข้าแตกต่างกันไปตามสถานะของอุปกรณ์ หากต้องการทำความเข้าใจสถานการณ์เหล่านี้และวิธีผสานรวม FCM เข้ากับแอปพลิเคชันของคุณเอง สิ่งสำคัญคือต้องกำหนดสถานะต่างๆ ที่อุปกรณ์สามารถอยู่ในนั้นได้ก่อน ดังนี้
| สถานะ | คำอธิบาย |
|---|---|
| เบื้องหน้า | เมื่อแอปพลิเคชันเปิดอยู่ กำลังแสดง และใช้งานอยู่ |
| เบื้องหลัง | เมื่อแอปพลิเคชันเปิดอยู่ แต่ทำงานอยู่ในเบื้องหลัง (ย่อเล็กสุด) โดยปกติแล้วสถานการณ์นี้จะเกิดขึ้นเมื่อผู้ใช้กดปุ่ม "หน้าแรก" ในอุปกรณ์ เปลี่ยนไปใช้แอปอื่นโดยใช้ตัวสลับแอป หรือเปิดแอปพลิเคชันในแท็บอื่น (เว็บ) |
| สิ้นสุด | เมื่ออุปกรณ์ล็อกอยู่หรือแอปพลิเคชันไม่ได้ทำงาน |
แอปพลิเคชันต้องมีคุณสมบัติตรงตามข้อกำหนดเบื้องต้นบางประการก่อนจึงจะรับเพย์โหลดของข้อความโดยใช้ FCM ได้ ดังนี้
- แอปพลิเคชันต้องเปิดอย่างน้อย 1 ครั้ง (เพื่อให้ลงทะเบียนกับ FCM ได้)
- ใน iOS หากผู้ใช้ปัดแอปพลิเคชันออกจากตัวสลับแอป ผู้ใช้ต้องเปิดแอปพลิเคชันอีกครั้งด้วยตนเองเพื่อให้ข้อความเบื้องหลังเริ่มทำงานอีกครั้ง
- ใน Android หากผู้ใช้บังคับปิดแอปจากการตั้งค่าอุปกรณ์ ผู้ใช้ต้องเปิดแอปอีกครั้งด้วยตนเองเพื่อให้ข้อความเริ่มทำงาน
- ในเว็บ คุณต้องขอโทเค็น (โดยใช้
getToken()) ด้วยใบรับรองการแจ้งเตือนแบบพุชบนเว็บ
ขอสิทธิ์รับข้อความ
ใน iOS, macOS, เว็บ และ Android 13 (ขึ้นไป) คุณต้องขอสิทธิ์จากผู้ใช้ก่อนจึงจะรับเพย์โหลดของ FCM ในอุปกรณ์ได้
แพ็กเกจ firebase_messaging มี API สำหรับขอสิทธิ์โดยใช้
เมธอด
requestPermission
API นี้ยอมรับอาร์กิวเมนต์ที่มีชื่อหลายรายการซึ่งกำหนดประเภทสิทธิ์ที่คุณต้องการขอ เช่น การระบุว่าการรับส่งข้อความที่มีเพย์โหลดการแจ้งเตือนสามารถทริกเกอร์เสียงหรืออ่านข้อความออกเสียงโดยใช้ Siri ได้หรือไม่ โดยค่าเริ่มต้น เมธอดจะขอสิทธิ์เริ่มต้นที่เหมาะสม API อ้างอิงมีเอกสารประกอบฉบับเต็มเกี่ยวกับวัตถุประสงค์ของสิทธิ์แต่ละรายการ
หากต้องการเริ่มต้นใช้งาน ให้เรียกเมธอดจากแอปพลิเคชันของคุณ (ใน iOS ระบบจะแสดงโมดัลในตัว ส่วนในเว็บ ระบบจะทริกเกอร์โฟลว์ API ของเบราว์เซอร์)
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
print('User granted permission: ${settings.authorizationStatus}');
คุณใช้พร็อพเพอร์ตี้ authorizationStatus ของออบเจ็กต์ NotificationSettings ที่ส่งคืนจากคำขอเพื่อกำหนดการตัดสินใจโดยรวมของผู้ใช้ได้ ดังนี้
authorized: ผู้ใช้ให้สิทธิ์denied: ผู้ใช้ปฏิเสธสิทธิ์notDetermined: ผู้ใช้ยังไม่ได้เลือกว่าจะให้สิทธิ์หรือไม่provisional: ผู้ใช้ให้สิทธิ์ชั่วคราว
พร็อพเพอร์ตี้อื่นๆ ใน NotificationSettings จะแสดงผลว่ามีการเปิดใช้ ปิดใช้ หรือไม่รองรับสิทธิ์ที่เฉพาะเจาะจงในอุปกรณ์ปัจจุบัน
เมื่อได้รับสิทธิ์และทำความเข้าใจสถานะต่างๆ ของอุปกรณ์แล้ว ตอนนี้แอปพลิเคชันของคุณจะเริ่มจัดการเพย์โหลดของ FCM ขาเข้าได้
การจัดการข้อความ
ข้อความเบื้องหน้า
หากต้องการจัดการข้อความขณะที่แอปพลิเคชันทำงานอยู่เบื้องหน้า ให้ฟังสตรีม onMessage
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message whilst in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
สตรีมมี RemoteMessage ซึ่งให้รายละเอียดข้อมูลต่างๆ เกี่ยวกับเพย์โหลด เช่น แหล่งที่มา, รหัสที่ไม่ซ้ำ, เวลาที่ส่ง, ข้อมูลว่ามีเพย์โหลดการแจ้งเตือนหรือไม่ และอื่นๆ เนื่องจากระบบดึงข้อความขณะที่แอปพลิเคชันทำงานอยู่เบื้องหน้า คุณจึงเข้าถึงสถานะและบริบทของแอปพลิเคชัน Flutter ได้โดยตรง
ข้อความเบื้องหน้าและการแจ้งเตือน
โดยค่าเริ่มต้น ข้อความแจ้งเตือนที่ได้รับขณะที่แอปพลิเคชันทำงานอยู่เบื้องหน้าจะไม่แสดงการแจ้งเตือนที่มองเห็นได้ ทั้งใน Android และ iOS อย่างไรก็ตาม คุณสามารถลบล้างลักษณะการทำงานนี้ได้โดยทำดังนี้
- ใน Android คุณต้องสร้างช่องทางการแจ้งเตือน "ลำดับความสำคัญสูง"
- ใน iOS คุณสามารถอัปเดตตัวเลือกการนำเสนอสำหรับแอปพลิเคชันได้
ข้อความเบื้องหลัง
กระบวนการจัดการข้อความเบื้องหลังจะแตกต่างกันในแพลตฟอร์มที่ใช้ Android, Apple และเว็บ
แพลตฟอร์ม Apple และ Android
จัดการข้อความเบื้องหลังโดยลงทะเบียนตัวแฮนเดิล onBackgroundMessage เมื่อได้รับข้อความ ระบบจะสร้างไอโซเลต (เฉพาะ Android เท่านั้น iOS/macOS ไม่ต้องใช้ไอโซเลตแยกต่างหาก) ซึ่งช่วยให้คุณจัดการข้อความได้แม้ว่าแอปพลิเคชันจะไม่ได้ทำงานอยู่ก็ตาม
สิ่งที่ควรทราบเกี่ยวกับตัวแฮนเดิลข้อความเบื้องหลังมีดังนี้
- ต้องไม่ใช่ฟังก์ชันที่ไม่ระบุชื่อ
- ต้องเป็นฟังก์ชันระดับบนสุด (เช่น ไม่ใช่เมธอดของคลาสที่ต้องมีการเริ่มต้น)
- เมื่อใช้ Flutter เวอร์ชัน 3.3.0 ขึ้นไป ตัวแฮนเดิลข้อความต้องมี
คำอธิบายประกอบ
@pragma('vm:entry-point')เหนือการประกาศฟังก์ชัน (มิเช่นนั้น ระบบอาจนำตัวแฮนเดิลออกระหว่างการทำ Tree Shaking สำหรับโหมดเผยแพร่)
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
}
void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
เนื่องจากตัวแฮนเดิลทำงานในไอโซเลตของตัวเองนอกบริบทของแอปพลิเคชัน คุณจึงไม่สามารถอัปเดตสถานะแอปพลิเคชันหรือเรียกใช้ตรรกะที่ส่งผลต่อ UI ได้ อย่างไรก็ตาม คุณสามารถดำเนินการตรรกะต่างๆ เช่น คำขอ HTTP, การดำเนินการ I/O (เช่น การอัปเดตพื้นที่เก็บข้อมูลในเครื่อง), การสื่อสารกับปลั๊กอินอื่นๆ เป็นต้น
นอกจากนี้ เราขอแนะนำให้คุณดำเนินการตรรกะให้เสร็จโดยเร็วที่สุด การเรียกใช้ฟังก์ชันที่ใช้เวลานานและใช้ทรัพยากรมากจะส่งผลต่อประสิทธิภาพของอุปกรณ์และอาจทำให้ระบบปฏิบัติการสิ้นสุดกระบวนการ หากฟังก์ชันทำงานนานกว่า 30 วินาที อุปกรณ์อาจหยุดกระบวนการโดยอัตโนมัติ
เว็บ
ในเว็บ ให้เขียน JavaScript Service Worker ที่ทำงานอยู่เบื้องหลัง ใช้ Service Worker เพื่อจัดการข้อความเบื้องหลัง
หากต้องการเริ่มต้นใช้งาน ให้สร้างไฟล์ใหม่ในไดเรกทอรี web แล้วตั้งชื่อไฟล์ว่า firebase-messaging-sw.js
// See this file for the latest firebase-js-sdk version:
// https://github.com/firebase/flutterfire/blob/main/packages/firebase_core/firebase_core_web/lib/src/firebase_sdk_version.dart
importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-messaging-compat.js");
firebase.initializeApp({
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
});
const messaging = firebase.messaging();
// Optional:
messaging.onBackgroundMessage((message) => {
console.log("onBackgroundMessage", message);
});
ไฟล์ต้องนำเข้าทั้ง SDK ของแอปและ SDK ของการรับส่งข้อความ เริ่มต้น Firebase และแสดงตัวแปร messaging
จากนั้นต้องลงทะเบียน Worker ลงทะเบียน Worker ภายในไฟล์ index.html โดยแก้ไขแท็ก <script> ที่เริ่มต้น Flutter ดังนี้
<script src="flutter_bootstrap.js" async>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('firebase-messaging-sw.js', {
scope: '/firebase-cloud-messaging-push-scope',
});
});
}
</script>
หากยังใช้ระบบการสร้างเทมเพลตแบบเก่าอยู่ คุณสามารถลงทะเบียน Worker ได้โดย
แก้ไขแท็ก <script> ที่เริ่มต้น Flutter ดังนี้
<html>
<body>
<script>
var serviceWorkerVersion = null;
var scriptLoaded = false;
function loadMainDartJs() {
if (scriptLoaded) {
return;
}
scriptLoaded = true;
var scriptTag = document.createElement('script');
scriptTag.src = 'main.dart.js';
scriptTag.type = 'application/javascript';
document.body.append(scriptTag);
}
if ('serviceWorker' in navigator) {
// Service workers are supported. Use them.
window.addEventListener('load', function () {
// Register Firebase Messaging service worker.
navigator.serviceWorker.register('firebase-messaging-sw.js', {
scope: '/firebase-cloud-messaging-push-scope',
});
// Wait for registration to finish before dropping the <script> tag.
// Otherwise, the browser will load the script multiple times,
// potentially different versions.
var serviceWorkerUrl =
'flutter_service_worker.js?v=' + serviceWorkerVersion;
navigator.serviceWorker.register(serviceWorkerUrl).then((reg) => {
function waitForActivation(serviceWorker) {
serviceWorker.addEventListener('statechange', () => {
if (serviceWorker.state == 'activated') {
console.log('Installed new service worker.');
loadMainDartJs();
}
});
}
if (!reg.active && (reg.installing || reg.waiting)) {
// No active web worker and we have installed or are installing
// one for the first time. Simply wait for it to activate.
waitForActivation(reg.installing ?? reg.waiting);
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
// When the app updates the serviceWorkerVersion changes, so we
// need to ask the service worker to update.
console.log('New service worker available.');
reg.update();
waitForActivation(reg.installing);
} else {
// Existing service worker is still good.
console.log('Loading app from service worker.');
loadMainDartJs();
}
});
// If service worker doesn't succeed in a reasonable amount of time,
// fallback to plaint <script> tag.
setTimeout(() => {
if (!scriptLoaded) {
console.warn(
'Failed to load app from service worker. Falling back to plain <script> tag.'
);
loadMainDartJs();
}
}, 4000);
});
} else {
// Service workers not supported. Just drop the <script> tag.
loadMainDartJs();
}
</script>
</body>
จากนั้นรีสตาร์ทแอปพลิเคชัน Flutter ระบบจะลงทะเบียน Worker และจัดการข้อความเบื้องหลังโดยใช้ไฟล์นี้
การจัดการการโต้ตอบ
เนื่องจากการแจ้งเตือนเป็นคิวที่มองเห็นได้ ผู้ใช้จึงมักจะโต้ตอบกับการแจ้งเตือน (โดยการกด) ลักษณะการทำงานเริ่มต้นในทั้ง Android และ iOS คือการเปิดแอปพลิเคชัน หากแอปพลิเคชันสิ้นสุดลง ระบบจะเริ่มแอปพลิเคชัน หากแอปพลิเคชันทำงานอยู่ในเบื้องหลัง ระบบจะนำแอปพลิเคชันขึ้นมาแสดงอยู่ในเบื้องหน้า
คุณอาจต้องการจัดการการโต้ตอบของผู้ใช้เมื่อแอปพลิเคชันเปิดขึ้น ทั้งนี้ขึ้นอยู่กับเนื้อหาของการแจ้งเตือน ตัวอย่างเช่น หากมีการส่งข้อความแชทใหม่โดยใช้การแจ้งเตือนและผู้ใช้กดการแจ้งเตือน คุณอาจต้องการเปิดการสนทนาที่เฉพาะเจาะจงเมื่อแอปพลิเคชันเปิดขึ้น
แพ็กเกจ firebase-messaging มี 2 วิธีในการจัดการการโต้ตอบนี้ ดังนี้
getInitialMessage(): หากเปิดแอปพลิเคชันจากสถานะสิ้นสุด ระบบจะแสดงผลFutureที่มีRemoteMessageเมื่อใช้แล้ว ระบบจะนำRemoteMessageออกonMessageOpenedApp:Streamที่โพสต์RemoteMessageเมื่อเปิดแอปพลิเคชันจากสถานะเบื้องหลัง
เราขอแนะนำให้จัดการทั้ง 2 สถานการณ์เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ราบรื่น ตัวอย่างโค้ดต่อไปนี้แสดงวิธีดำเนินการนี้
class Application extends StatefulWidget {
@override
State<StatefulWidget> createState() => _Application();
}
class _Application extends State<Application> {
// It is assumed that all messages contain a data field with the key 'type'
Future<void> setupInteractedMessage() async {
// Get any messages which caused the application to open from
// a terminated state.
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
// If the message also contains a data property with a "type" of "chat",
// navigate to a chat screen
if (initialMessage != null) {
_handleMessage(initialMessage);
}
// Also handle any interaction when the app is in the background using a
// Stream listener
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
}
void _handleMessage(RemoteMessage message) {
if (message.data['type'] == 'chat') {
Navigator.pushNamed(context, '/chat',
arguments: ChatArguments(message),
);
}
}
@override
void initState() {
super.initState();
// Run code required to handle interacted messages in an async function
// as initState() must not be async
setupInteractedMessage();
}
@override
Widget build(BuildContext context) {
return Text("...");
}
}
วิธีจัดการการโต้ตอบจะขึ้นอยู่กับการตั้งค่าแอปพลิเคชัน ตัวอย่างก่อนหน้าแสดงภาพประกอบพื้นฐานโดยใช้ StatefulWidget
แปลข้อความเป็นภาษาท้องถิ่น
คุณสามารถส่งสตริงที่แปลเป็นภาษาท้องถิ่นได้ 2 วิธี ดังนี้
- จัดเก็บภาษาที่ต้องการของผู้ใช้แต่ละรายไว้ในเซิร์ฟเวอร์และส่งการแจ้งเตือนที่ปรับแต่งสำหรับแต่ละภาษา
- ฝังสตริงที่แปลเป็นภาษาท้องถิ่นไว้ในแอปและใช้การตั้งค่าภาษาในตัวของระบบปฏิบัติการ
วิธีใช้เมธอดที่ 2 มีดังนี้
Android
ระบุข้อความภาษาเริ่มต้นใน
resources/values/strings.xml<string name="notification_title">Hello world</string> <string name="notification_message">This is a message</string>ระบุข้อความที่แปลแล้วในไดเรกทอรี
values-languageเช่น ระบุข้อความภาษาฝรั่งเศสในresources/values-fr/strings.xml<string name="notification_title">Bonjour le monde</string> <string name="notification_message">C'est un message</string>ในเพย์โหลดของเซิร์ฟเวอร์ ให้ใช้คีย์
title_loc_keyและbody_loc_keyสำหรับข้อความที่แปลเป็นภาษาท้องถิ่นแทนการใช้คีย์title,message, และbodyแล้วตั้งค่าคีย์เหล่านี้เป็นแอตทริบิวต์nameของข้อความที่ต้องการแสดงเพย์โหลดของข้อความจะมีลักษณะดังนี้
{ "android": { "notification": { "title_loc_key": "notification_title", "body_loc_key": "notification_message" } } }
iOS
ระบุข้อความภาษาเริ่มต้นใน
Base.lproj/Localizable.strings"NOTIFICATION_TITLE" = "Hello World"; "NOTIFICATION_MESSAGE" = "This is a message";ระบุข้อความที่แปลแล้วในไดเรกทอรี
language.lprojเช่น ระบุข้อความภาษาฝรั่งเศสในfr.lproj/Localizable.strings"NOTIFICATION_TITLE" = "Bonjour le monde"; "NOTIFICATION_MESSAGE" = "C'est un message";เพย์โหลดของข้อความจะมีลักษณะดังนี้
{ "apns": { "payload": { "alert": { "title-loc-key": "NOTIFICATION_TITLE", "loc-key": "NOTIFICATION_MESSAGE" } } } }
เปิดใช้การส่งออกข้อมูลการส่งข้อความ
คุณสามารถส่งออกข้อมูลข้อความไปยัง BigQuery เพื่อวิเคราะห์เพิ่มเติมได้ BigQuery ช่วยให้คุณวิเคราะห์ข้อมูลโดยใช้ BigQuery SQL, ส่งออกข้อมูลไปยังผู้ให้บริการคลาวด์รายอื่น หรือใช้ข้อมูลสำหรับโมเดล ML ที่กำหนดเอง การส่งออกไปยัง BigQuery จะรวมข้อมูลทั้งหมดที่พร้อมใช้งานสำหรับข้อความ ไม่ว่าจะเป็นข้อความประเภทใดหรือส่งข้อความโดยใช้ API หรือเครื่องมือแต่งการแจ้งเตือน
หากต้องการเปิดใช้การส่งออก ให้ทำตามขั้นตอนในเอกสารการส่งออกข้อมูล BigQuery ก่อน การเปิดใช้การส่งออกข้อมูลในระดับ อินสแตนซ์ของแอปโดยใช้โปรแกรมจะช่วยให้คุณขอสิทธิ์จากผู้ใช้ปลายทางในการวิเคราะห์ข้อมูลการส่งข้อความของผู้ใช้ได้ (แนะนำ) ทำตามวิธีการต่อไปนี้เพื่อเปิดใช้การส่งออกข้อมูลโดยใช้โปรแกรม
Android
คุณสามารถใช้โค้ดต่อไปนี้
await FirebaseMessaging.instance.setDeliveryMetricsExportToBigQuery(true);
iOS
สำหรับ iOS คุณต้องเปลี่ยน AppDelegate.m ด้วยเนื้อหาต่อไปนี้
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
#import <Firebase/Firebase.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[[FIRMessaging extensionHelper] exportDeliveryMetricsToBigQueryWithMessageInfo:userInfo];
}
@end
เว็บ
สำหรับเว็บ คุณต้องเปลี่ยน Service Worker เพื่อใช้ SDK เวอร์ชัน v9 คุณต้องรวมเวอร์ชัน v9 ไว้ด้วยกัน ดังนั้นคุณจึงต้องใช้เครื่องมือรวม เช่น esbuild เพื่อให้ Service Worker ทำงานได้ ดูแอปตัวอย่าง
เพื่อดูวิธีดำเนินการนี้
เมื่อย้ายข้อมูลไปยัง SDK เวอร์ชัน v9 แล้ว คุณจะใช้โค้ดต่อไปนี้ได้
import {
experimentalSetDeliveryMetricsExportedToBigQueryEnabled,
getMessaging,
} from 'firebase/messaging/sw';
...
const messaging = getMessaging(app);
experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, true);
อย่าลืมเรียกใช้ yarn build เพื่อส่งออก Service Worker เวอร์ชันใหม่ไปยังโฟลเดอร์ web
แสดงรูปภาพในการแจ้งเตือนบน iOS
ในอุปกรณ์ Apple หากต้องการให้การแจ้งเตือน FCM ขาเข้าแสดงรูปภาพจากเพย์โหลดของ FCM คุณต้องเพิ่มส่วนขยายบริการการแจ้งเตือนเพิ่มเติมและกำหนดค่าแอปให้ใช้ส่วนขยายดังกล่าว
หากใช้การตรวจสอบสิทธิ์ทางโทรศัพท์ของ Firebase คุณต้องเพิ่ม Pod ของ Firebase Auth ลงใน Podfile
ขั้นตอนที่ 1 - เพิ่มส่วนขยายบริการการแจ้งเตือน
- ใน Xcode ให้คลิกFile > New > Target...
- โมดัลจะแสดงรายการเป้าหมายที่เป็นไปได้ ให้เลื่อนหรือใช้ตัวกรองเพื่อเลือกNotification Service Extension คลิกNext
- เพิ่มชื่อผลิตภัณฑ์ (ใช้ "ImageNotification" เพื่อทำตามบทแนะนำนี้) เลือก
SwiftหรือObjective-Cแล้วคลิกFinish - เปิดใช้สคีมาโดยคลิกActivate
ขั้นตอนที่ 2 - เพิ่มเป้าหมายลงใน Podfile
Swift
ตรวจสอบว่าส่วนขยายใหม่มีสิทธิ์เข้าถึงแพ็กเกจ Swift ของ FirebaseMessaging โดยเพิ่มแพ็กเกจลงในเป้าหมาย Runner ดังนี้
จาก Navigator ให้เพิ่ม SDK ของแพลตฟอร์ม Apple ของ Firebase โดยไปที่ File > Add Package Dependencies...
ค้นหาหรือป้อน URL ของแพ็กเกจ:
none https://github.com/firebase/firebase-ios-sdkเพิ่มลงในโปรเจ็กต์
Runnerโดยไปที่ Add Packageเลือก FirebaseMessaging แล้วเพิ่มลงในเป้าหมาย ImageNotification โดยไปที่ Add Package
Objective-C
ตรวจสอบว่าส่วนขยายใหม่มีสิทธิ์เข้าถึง Pod ของ Firebase/Messaging โดยเพิ่ม Pod ลงใน Podfile ดังนี้
จาก Navigator ให้เปิด Podfile โดยไปที่ Pods > Podfile
ไปที่ด้านล่างของไฟล์แล้วเพิ่มโค้ดต่อไปนี้
target 'ImageNotification' do use_frameworks! pod 'Firebase/Auth' # Add this line if you are using FirebaseAuth phone authentication pod 'Firebase/Messaging' endติดตั้งหรืออัปเดต Pod โดยใช้
pod installจากไดเรกทอรีiosหรือmacos
ขั้นตอนที่ 3 - ใช้ตัวช่วยส่วนขยาย
ตอนนี้ทุกอย่างควรยังทำงานได้ตามปกติ ขั้นตอนสุดท้ายคือการเรียกใช้ตัวช่วยส่วนขยาย
Swift
จาก Navigator ให้เลือกส่วนขยาย ImageNotification
เปิดไฟล์
NotificationService.swiftแทนที่เนื้อหาของ
NotificationService.swiftด้วยโค้ดต่อไปนี้import UserNotifications import FirebaseMessaging class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) Messaging.serviceExtension().populateNotificationContent(bestAttemptContent!, withContentHandler: contentHandler) } override func serviceExtensionTimeWillExpire() { if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } }
Objective-C
จาก Navigator ให้เลือกส่วนขยาย ImageNotification
เปิดไฟล์
NotificationService.mที่ด้านบนของไฟล์ ให้นำเข้า
FirebaseMessaging.hทันทีหลังจากNotificationService.hแทนที่เนื้อหาของ
NotificationService.mด้วยโค้ดต่อไปนี้#import "NotificationService.h" #import "FirebaseMessaging.h" #import <FirebaseAuth/FirebaseAuth-Swift.h> // Add this line if you are using FirebaseAuth phone authentication #import <UIKit/UIKit.h> // Add this line if you are using FirebaseAuth phone authentication @interface NotificationService () <NSURLSessionDelegate> @property(nonatomic) void (^contentHandler)(UNNotificationContent *contentToDeliver); @property(nonatomic) UNMutableNotificationContent *bestAttemptContent; @end @implementation NotificationService /* Uncomment this if you are using Firebase Auth - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options { if ([[FIRAuth auth] canHandleURL:url]) { return YES; } return NO; } - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts { for (UIOpenURLContext *urlContext in URLContexts) { [FIRAuth.auth canHandleURL:urlContext.URL]; } } */ - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; // Modify the notification content here... [[FIRMessaging extensionHelper] populateNotificationContent:self.bestAttemptContent withContentHandler:contentHandler]; } - (void)serviceExtensionTimeWillExpire { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. self.contentHandler(self.bestAttemptContent); } @end
ขั้นตอนที่ 4 - เพิ่มรูปภาพลงในเพย์โหลด
ตอนนี้คุณสามารถเพิ่มรูปภาพลงในเพย์โหลดการแจ้งเตือนได้แล้ว ดูข้อมูลเพิ่มเติมได้ที่วิธีสร้างคำขอส่ง