Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีใช้ Firebase Messaging (FCM) ในแอป Android

ภาพรวม

ตัวอย่างนี้แสดงวิธีรวม Firebase Cloud Messaging (FCM) ในแอป Android เพื่อรับ Push Notification พร้อมการสร้าง Notification Channel สำหรับ Android 8.0+

ขั้นตอนการตั้งค่า Firebase

1. สร้างโปรเจกต์ใน Firebase Console

  • เข้า Firebase Console
  • Add Project → ใส่ชื่อโปรเจกต์
  • Enable Google Analytics (ถ้าต้องการ)

2. เพิ่ม Android App

  • คลิก Android Icon (
  • Package Name: com.example.myapplication
  • Download google-services.json → วางใน app/

3. เพิ่ม Dependency

// Project-level build.gradle
dependencies {
    classpath 'com.google.gms:google-services:4.4.0'
}

// App-level build.gradle
plugins {
    id 'com.android.application'
    id 'com.google.gms.google-services'
}

dependencies {
    implementation platform('com.google.firebase:firebase-bom:32.7.0')
    implementation 'com.google.firebase:firebase-messaging'
    implementation 'com.google.firebase:firebase-analytics'
}

โค้ดการรับข้อความ (src/MyFirebaseMessagingService.java)

package com.example.myapplication;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import org.json.JSONObject;
import java.util.Map;

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "FCMService";
    private static final String CHANNEL_ID = "default_notifications";

    @Override
    public void onNewToken(String token) {
        super.onNewToken(token);
        Log.d(TAG, "FCM Token: " + token);
        // ส่ง Token ไป Server ของคุณ
        sendTokenToServer(token);
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        
        // 1. Data Message (จาก Server ส่งมันมาเอง)
        if (remoteMessage.getData().size() > 0) {
            Map<String, String> data = remoteMessage.getData();
            Log.d(TAG, "Data payload: " + data);
            handleDataMessage(data);
        }
        
        // 2. Notification Message (Firebase Console / Auto display)
        if (remoteMessage.getNotification() != null) {
            String title = remoteMessage.getNotification().getTitle();
            String body = remoteMessage.getNotification().getBody();
            Log.d(TAG, "Notification: " + title + " - " + body);
            showNotification(title, body, remoteMessage.getData());
        }
    }

    private void handleDataMessage(Map<String, String> data) {
        // ประมวลผลข้อมูลแบบ Custom (Silent push, Background sync, etc.)
        try {
            JSONObject json = new JSONObject(data);
            // Parse และทำตาม Business Logic
        } catch (Exception e) {
            Log.e(TAG, "JSON Parse error", e);
        }
    }

    private void showNotification(String title, String body, Map<String, String> data) {
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        
        // สร้าง Channel สำหรับ Android O+
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                CHANNEL_ID, 
                "Default Notifications", 
                NotificationManager.IMPORTANCE_HIGH
            );
            channel.setDescription("General app notifications");
            channel.enableLights(true);
            channel.setLightColor(Color.RED);
            channel.enableVibration(true);
            channel.setVibrationPattern(new long[]{0, 500, 200, 500});
            channel.setBypassDnd(true); // แสดงแม้ Do Not Disturb
            manager.createNotificationChannel(channel);
        }
        
        // สร้าง Notification
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_notification) // ต้องมี icon นี้ใน drawable
            .setContentTitle(title != null ? title : getString(R.string.app_name))
            .setContentText(body != null ? body : "New message")
            .setAutoCancel(true)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setDefaults(NotificationCompat.DEFAULT_ALL)
            .setWhen(System.currentTimeMillis())
            .setColor(ContextCompat.getColor(this, R.color.colorAccent));
        
        // เพิ่ม Action (ถ้าต้องการ)
        // builder.addAction(R.drawable.ic_reply, "Reply", replyPendingIntent);
        
        manager.notify((int) System.currentTimeMillis(), builder.build());
    }
    
    private void sendTokenToServer(String token) {
        // TODO: Implement server registration
    }
}

AndroidManifest.xml

<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- Android 13+ -->
    
    <application ...>
        <service
            android:name=".MyFirebaseMessagingService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
        
        <!-- Default Notification Icon & Color -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/ic_notification" />
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/colorAccent" />
            
        <!-- Default Channel (Android 8.0+) -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="default_notifications" />
    </application>
</manifest>

ประเภทข้อความ FCM

ประเภทคุณสมบัติการจัดการ
Notification Messageมี title/body, แสดงอัตโนมัติเมื่อ App ใน BackgroundonMessageReceived() ไม่ถูกเรียกใน Background
Data Messageมี key-value เท่านั้น, ไม่แสดงอัตโนมัติonMessageReceived() เรียกได้ตลอด (Fore/Background)
Bothมีทั้ง notification และ dataBackground: แสดง notification, Foreground: onMessageReceived()

การขอสิทธิ์ Notification (Android 13+)

// ใน Activity
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, 1001);
    }
}

การทดสอบจาก Firebase Console

  1. Firebase Console → Messaging → Create Campaign
  2. Notification Title/Body → Next
  3. Target: Select App → Next
  4. Schedule: Now → Next
  5. Additional Options: Custom Data (Key/Value) → Next
  6. Review → Publish

Debug: ดู FCM Token

// ใน Activity
FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(task -> {
        if (task.isSuccessful()) {
            String token = task.getResult();
            Log.d("FCM", "Token: " + token);
            // Copy token นี้ไปทดสอบส่งจาก Server/Postman
        }
    });

สรุป Checklist

  • [ ] google-services.json ใน app/
  • [ ] google-services plugin ใน build.gradle
  • [ ] firebase-messaging dependency
  • [ ] Service extends FirebaseMessagingService ใน Manifest
  • [ ] Notification Channel สำหรับ Android 8+
  • [ ] POST_NOTIFICATIONS permission สำหรับ Android 13+
  • [ ] Default icon/color/channel ใน Manifest
  • [ ] Handle onNewToken() ส่งไป Server
  • [ ] Handle onMessageReceived() สำหรับ Data Message