เริ่มต้นใช้งาน Firebase Cloud Messaging ในแอป Flutter

เลือกแพลตฟอร์ม iOS+ Android Web Flutter Unity C++


คู่มือนี้อธิบายวิธีเริ่มต้นใช้งาน Firebase Cloud Messaging ในแอปไคลเอ็นต์ Flutter เพื่อให้คุณส่งข้อความได้อย่างน่าเชื่อถือ

คุณจะต้องทำตามขั้นตอนการตั้งค่าเพิ่มเติมที่จำเป็น ทั้งนี้ขึ้นอยู่กับแพลตฟอร์มที่คุณกำหนดเป้าหมาย

iOS+

การแลกเปลี่ยนเมธอด

หากต้องการใช้ปลั๊กอิน Flutter ของ FCM ในอุปกรณ์ Apple คุณต้องใช้การแลกเปลี่ยนเมธอด หากไม่มีสิทธิ์นี้ ฟีเจอร์หลักของ Firebase เช่น การจัดการการลงทะเบียน FCM จะทำงานไม่ถูกต้อง

Android

บริการ Google Play

ไคลเอ็นต์ FCM ต้องใช้อุปกรณ์ที่ใช้ Android 7.0 ขึ้นไปซึ่งติดตั้งบริการ Google Play ไว้ด้วย หรือโปรแกรมจำลองที่ใช้ Android 7.0 ที่มี Google APIs โปรดทราบว่าคุณไม่จำเป็นต้องติดตั้งใช้งานแอป Android ผ่าน Google Play Store เท่านั้น

แอปที่ใช้ SDK ของบริการ Google Play ควรตรวจสอบอุปกรณ์เพื่อหา APK ของบริการ Google Play ที่เข้ากันได้ก่อนเข้าถึงฟีเจอร์ของบริการ Google Play เสมอ เราขอแนะนำให้ดำเนินการนี้ใน 2 ตำแหน่ง ได้แก่ ในเมธอด onCreate() ของกิจกรรมหลัก และในเมธอด onResume() การตรวจสอบใน onCreate() ช่วยให้มั่นใจว่าแอปจะใช้งานไม่ได้หากไม่ผ่านการตรวจสอบ การตรวจสอบใน onResume() ช่วยให้มั่นใจว่าหากผู้ใช้กลับไปยังแอปที่ทำงานอยู่ด้วยวิธีอื่น เช่น ผ่านปุ่มย้อนกลับ ระบบจะยังคงทำการตรวจสอบอยู่

หากอุปกรณ์ไม่มีบริการ Google Play เวอร์ชันที่เข้ากันได้ แอปของคุณจะเรียกใช้ GoogleApiAvailability.makeGooglePlayServicesAvailable() เพื่ออนุญาตให้ผู้ใช้ดาวน์โหลดบริการ Google Play จาก Play Store ได้

เว็บ

กำหนดค่าข้อมูลเข้าสู่ระบบเว็บด้วย FCM

อินเทอร์เฟซเว็บของ FCM ใช้ข้อมูลเข้าสู่ระบบเว็บที่เรียกว่า Voluntary Application Server Identification หรือคีย์ "VAPID" เพื่อให้สิทธิ์ส่งคำขอไปยังบริการพุชบนเว็บที่รองรับ หากต้องการสมัครรับข้อความ Push ให้แอป คุณต้องเชื่อมโยงคู่คีย์กับโปรเจ็กต์ Firebase คุณสามารถสร้างคู่คีย์ใหม่หรือนำเข้าคู่คีย์ที่มีอยู่ผ่านคอนโซล Firebase ก็ได้

ติดตั้งปลั๊กอิน FCM

  1. ติดตั้งและเริ่มต้นปลั๊กอิน Firebase สำหรับ Flutter หากยังไม่ได้ดำเนินการ

  2. จากรูทของโปรเจ็กต์ Flutter ให้เรียกใช้คำสั่งต่อไปนี้เพื่อติดตั้งปลั๊กอิน

    flutter pub add firebase_messaging
    
  3. เมื่อเสร็จแล้ว ให้สร้างแอปพลิเคชัน Flutter อีกครั้งโดยทำดังนี้

    flutter run
    

ขอสิทธิ์การแจ้งเตือน

หากต้องการส่งข้อความแจ้งเตือนไปยังอุปกรณ์ คุณต้องลงทะเบียนอุปกรณ์กับ FCM โดยใช้ register() หากไม่ได้รับสิทธิ์การแจ้งเตือน เมธอดนี้จะขอสิทธิ์การแจ้งเตือนจากผู้ใช้ ไม่เช่นนั้น ระบบจะส่ง FID ผ่าน onRegistered เมื่อดำเนินการสำเร็จหรือปฏิเสธการดำเนินการในอนาคตเนื่องจากข้อผิดพลาด

// You may set the permission requests to "provisional" which allows the user to choose what type
// of notifications they would like to receive once the user receives a notification.
final notificationSettings = await FirebaseMessaging.instance.requestPermission(provisional: true);

// For apple platforms, make sure the APNS token is available before making any FCM plugin API calls
final apnsToken = await FirebaseMessaging.instance.getAPNSToken();
if (apnsToken != null) {
 // APNS token is available, make FCM plugin API requests...
}

เข้าถึงรหัสการติดตั้ง Firebase

เปิดใช้การลงทะเบียนโดยใช้รหัสการติดตั้ง Firebase

หากต้องการเปิดใช้การลงทะเบียนอินสแตนซ์แอปกับ FCM โดยใช้รหัสการติดตั้ง Firebase (FID) คุณต้องเปิดใช้ FID ในการกำหนดค่าของแอปสำหรับแพลตฟอร์ม Android และ Apple ก่อน (ไม่จำเป็นต้องมีการกำหนดค่าการเลือกใช้แบบคงที่บนเว็บ)

Android

เพิ่มองค์ประกอบ <meta-data> ต่อไปนี้ภายในองค์ประกอบ <application> ของ AndroidManifest.xml:

<meta-data android:name="firebase_messaging_installation_id_enabled"
           android:value="true" />

iOS+

เพิ่มคีย์ FirebaseMessagingInstallationIdEnabled ลงใน Info.plist และตั้งค่าเป็น true (YES) ดังนี้

<key>FirebaseMessagingInstallationIdEnabled</key>
<true/>

สมัครรับสตรีม onRegistered

หากต้องการส่งข้อความไปยังอินสแตนซ์แอปในอุปกรณ์ที่เฉพาะเจาะจง คุณต้องมีรหัสการติดตั้ง Firebase (FID) ของอินสแตนซ์แอปนั้นเมื่อลงทะเบียนกับ FCM แล้ว ระบบจะส่ง FID แบบอะซิงโครนัสผ่านสตรีม onRegistered

ในแพลตฟอร์ม Android และ Apple FCM จะลงทะเบียนอินสแตนซ์แอปโดยอัตโนมัติเมื่อเริ่มต้นระบบเมื่อเปิดใช้การเริ่มต้นอัตโนมัติ (ค่าเริ่มต้น) อย่างไรก็ตาม คุณต้องเรียกใช้ register() อย่างชัดเจน ดังนี้

  • ในเว็บ คุณสามารถส่ง vapidKey และ serviceWorkerScriptPath ได้ (ไม่บังคับ)
  • ในแพลตฟอร์ม Android และ Apple หากปิดใช้การเริ่มต้นอัตโนมัติหรือหลังจากเรียกใช้ unregister() นอกจากนี้ คุณยังเรียกใช้ register() ได้ทุกเมื่อเพื่อทริกเกอร์ onRegistered ด้วย FID ที่ลงทะเบียนไว้แล้ว

สมัครรับข้อมูล onRegistered ก่อนเรียกใช้ register() เสมอเพื่อให้ Listener ทำงานเมื่อมีการส่งเหตุการณ์การลงทะเบียน

final messaging = FirebaseMessaging.instance;

messaging.onRegistered
    .listen((String installationId) {
      // TODO: Send the Firebase Installation ID (FID) to your application server.
    })
    .onError((err) {
      // Error getting Firebase Installation ID.
    });

// Required on Web, and on Android/Apple if auto-initialization is disabled.
await messaging.register(
  // Optional on Web (ignored on Android and Apple platforms)
  vapidKey: "BKagOny0KF_2pCJQ3m....moL0ewzQ8rZu",
);

สตรีม onRegistered จะส่ง FID ในสถานการณ์ต่อไปนี้

  1. โดยอัตโนมัติเมื่อเริ่มต้นแอปครั้งแรกและซิงค์เป็นประจำในแพลตฟอร์ม Android และ Apple เมื่อเปิดใช้การเริ่มต้นอัตโนมัติ
  2. ทุกครั้งที่การเรียกใช้ register() ด้วยตนเองเสร็จสิ้น (แม้ว่าอินสแตนซ์ของแอปจะลงทะเบียนแล้ว แต่ onRegistered จะยังคงส่ง FID ที่ลงทะเบียนแล้ว)
  3. เมื่อใดก็ตามที่ตรวจพบการเปลี่ยนแปลงรหัสการติดตั้ง Firebase และมีการลงทะเบียนแอปกับ FCM อีกครั้ง หรือบนเว็บเมื่อมีการเริ่มเหตุการณ์ pushsubscriptionchange

หลังจากได้รับรหัสการติดตั้ง Firebase (FID) แล้ว ให้ส่งรหัสดังกล่าวไปยังเซิร์ฟเวอร์แอปและจัดเก็บโดยใช้วิธีที่ต้องการ

เข้าถึงโทเค็นการลงทะเบียน (เลิกใช้งานแล้ว)

หากต้องการส่งข้อความไปยังอุปกรณ์ที่เฉพาะเจาะจง คุณต้องทราบโทเค็นการลงทะเบียนอุปกรณ์ หากต้องการดึงข้อมูลโทเค็นการลงทะเบียนสำหรับอินสแตนซ์แอป ให้เรียกใช้ getToken() หากไม่ได้รับสิทธิ์การแจ้งเตือน เมธอดนี้จะขอสิทธิ์การแจ้งเตือนจากผู้ใช้ ไม่เช่นนั้น ระบบจะแสดงผลโทเค็นหรือปฏิเสธ Future เนื่องจากข้อผิดพลาด

ในแพลตฟอร์มเว็บ ให้ส่งคีย์สาธารณะ VAPID ไปยัง getToken():

final fcmToken = await FirebaseMessaging.instance.getToken(vapidKey: "BKagOny0KF_2pCJQ3m....moL0ewzQ8rZu");

หากต้องการรับการแจ้งเตือนทุกครั้งที่มีการอัปเดตโทเค็น ให้สมัครรับข้อมูลสตรีม onTokenRefresh ดังนี้

FirebaseMessaging.instance.onTokenRefresh
    .listen((fcmToken) {
      // TODO: If necessary send token to application server.

      // Note: This callback is fired at each app startup and whenever a new
      // token is generated.
    })
    .onError((err) {
      // Error getting token.
    });

ป้องกันการเริ่มต้นอัตโนมัติ

เมื่อมีการสร้างการลงทะเบียน FCM ไลบรารีจะอัปโหลดตัวระบุและข้อมูลการกำหนดค่าไปยัง Firebase หากต้องการป้องกันการลงทะเบียนอัตโนมัติ ให้ปิดใช้การเริ่มต้นอัตโนมัติในเวลาบิลด์

เมื่อปิดใช้การเริ่มต้นอัตโนมัติ คุณสามารถลงทะเบียนอินสแตนซ์แอปอย่างชัดแจ้งที่รันไทม์ได้โดยเรียกใช้ register() (อย่าลืมสมัครรับข้อมูล onRegistered ก่อนเพื่อรับรหัสการติดตั้ง Firebase) ดังนี้

await FirebaseMessaging.instance.register();

iOS

ใน iOS ให้เพิ่มค่าข้อมูลเมตาลงใน Info.plist ดังนี้

FirebaseMessagingAutoInitEnabled = NO

Android

ใน Android ให้ปิดใช้การรวบรวมข้อมูล Analytics และการเริ่มต้น FCM อัตโนมัติ (คุณต้องปิดใช้ทั้ง 2 อย่าง) โดยเพิ่มค่าข้อมูลเมตาเหล่านี้ลงใน AndroidManifest.xml

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

เปิดใช้การเริ่มต้นอัตโนมัติของ FCM อีกครั้งที่รันไทม์

หากต้องการเปิดใช้การเริ่มต้นอัตโนมัติสำหรับอินสแตนซ์แอปที่เฉพาะเจาะจง ให้เรียกใช้ setAutoInitEnabled() ดังนี้

await FirebaseMessaging.instance.setAutoInitEnabled(true);

ค่านี้จะยังคงอยู่เมื่อรีสตาร์ทแอปเมื่อตั้งค่าแล้ว

ส่งข้อความแจ้งเตือนทดสอบ

  1. ติดตั้งและเรียกใช้แอปในอุปกรณ์เป้าหมาย ในอุปกรณ์ Apple คุณจะต้องยอมรับคำขอสิทธิ์เพื่อรับการแจ้งเตือนระยะไกล

  2. ตรวจสอบว่าแอปทำงานอยู่เบื้องหลังในอุปกรณ์

  3. ในคอนโซล Firebase ให้ไปที่ DevOps และการมีส่วนร่วม > การรับส่งข้อความ

  4. สร้างแคมเปญ

    • หากนี่เป็นข้อความแรกของคุณ ให้ทำดังนี้

      1. เลือกสร้างแคมเปญแรก

      2. เลือกข้อความแจ้งเตือนของ Firebase แล้วเลือกสร้าง

    • หากคุณเคยสร้างแคมเปญไว้ก่อนหน้านี้ ให้ทำดังนี้

      1. ในแท็บแคมเปญ ให้เลือกแคมเปญใหม่

      2. คลิกการแจ้งเตือน

  5. ป้อนข้อความ

  6. เลือกส่งข้อความทดสอบจากแผงด้านขวา

  7. ในช่องที่มีป้ายกำกับว่าเพิ่มรหัสการติดตั้ง Firebase หรือFCM โทเค็นการลงทะเบียน ให้ป้อนรหัสการติดตั้ง Firebase หรือโทเค็นการลงทะเบียนที่ลงทะเบียนไว้

  8. เลือกทดสอบ

หลังจากเลือกทดสอบแล้ว อุปกรณ์ไคลเอ็นต์เป้าหมายที่มีแอปทำงานอยู่เบื้องหลังควรได้รับการแจ้งเตือน

หากต้องการดูข้อมูลเชิงลึกเกี่ยวกับการส่งข้อความไปยังแอป ให้ไปที่แดชบอร์ดDevOps และการมีส่วนร่วม > การรับส่งข้อความ > รายงานในคอนโซล Firebase แดชบอร์ดนี้จะบันทึกจำนวนข้อความที่ส่งและเปิดในอุปกรณ์ Apple และอุปกรณ์ Android พร้อมกับข้อมูล "การแสดงผล" (การแจ้งเตือนที่ผู้ใช้เห็น) สำหรับแอป Android

การจัดการการโต้ตอบ

เมื่อผู้ใช้แตะการแจ้งเตือน ลักษณะการทำงานเริ่มต้นทั้งใน Android และ iOS คือการเปิดแอปพลิเคชัน หากแอปพลิเคชันถูกสิ้นสุดการทำงาน ระบบจะเริ่มแอปพลิเคชัน และหากแอปพลิเคชันทำงานอยู่เบื้องหลัง ระบบจะนำแอปพลิเคชันมาทำงานอยู่เบื้องหน้า

คุณอาจต้องจัดการการโต้ตอบของผู้ใช้เมื่อแอปพลิเคชันเปิดขึ้น ทั้งนี้ขึ้นอยู่กับเนื้อหาของการแจ้งเตือน เช่น หากมีการส่งข้อความแชทใหม่โดยใช้การแจ้งเตือนและผู้ใช้เลือกข้อความนั้น คุณอาจต้องการเปิดการสนทนาที่เฉพาะเจาะจงเมื่อแอปพลิเคชันเปิดขึ้น

แพ็กเกจ firebase-messaging มี 2 วิธีในการจัดการการโต้ตอบนี้ ได้แก่

  1. getInitialMessage(): หากแอปพลิเคชันเปิดจากสถานะสิ้นสุด เมธอดนี้จะแสดงผล Future ที่มี RemoteMessage เมื่อใช้แล้ว ระบบจะนำ RemoteMessage ออก
  2. onMessageOpenedApp: Stream ซึ่งจะโพสต์ RemoteMessage เมื่อเปิดแอปพลิเคชันจากสถานะเบื้องหลัง

คุณควรจัดการทั้ง 2 สถานการณ์เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ราบรื่น ตัวอย่างโค้ดต่อไปนี้แสดงวิธีดำเนินการดังกล่าว

class Application extends StatefulWidget {
  @override
  State createState() => _Application();
}

class _Application extends State {
  // In this example, suppose that all messages contain a data field with the key 'type'.
  Future 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

ขั้นตอนถัดไป

หลังจากทำตามขั้นตอนการตั้งค่าเสร็จแล้ว คุณมีตัวเลือกต่อไปนี้ในการดำเนินการต่อด้วย FCM สำหรับ Flutter