بااستفاده از FCM AndroidConfigV2، میتوانید پیامهای مبتنی بر هدف را با ارسال بهموقع اعلان و میانای برنامهسازی کاربردی سادهشده به دستگاههای Android ارسال کنید.
این راهنما نحوه انتقال درخواستهای ارسال زیرینه از AndroidConfig
به AndroidConfigV2 و نحوه بهروزرسانی مشتریان برنامه Android
از رسیدگی قدیمی onMessageReceived به فراخوانیهای برگشتی مشتری نسخه ۲ جدید
onNotificationReceived و onBackgroundSyncReceived را پوشش میدهد.
ویژگیهای جدید AndroidConfigV2
FCM AndroidConfigV2 API با معرفی دو نوع پیام، تجربه توسعهدهنده را ساده میکند:
RemoteNotification: برای همه پیامهای FCM که اعلان فوری و حساس به زمان قابلمشاهده برای کاربر را نمایش میدهند توصیه میشود. این پیامها هرگونه اقدام صرفهجویی در مصرف باتری را دور میزنند و بدون تأخیر تحویل داده میشوند. در دستگاه، کیت توسعه نرمافزار FCM و «خدمات Google Play» مالکیت پست کردن اعلان درNotificationManagerAndroid را برعهده میگیرند.BackgroundSync: پیامهای داده غیرفوری که برای همگامسازی پسزمینه و بهروزرسانی وضعیت برنامه درنظر گرفته شدهاند. برای بهینهسازی عمر باتری، ممکن است تحویل بهصورت دستهای یا با تأخیر انجام شود.
| ویژگی | قدیمی (AndroidConfig v1) |
جدید (AndroidConfigV2) |
|---|---|---|
| فیلد پیکربندی | message.android |
message.android_v2 |
| تعریف اولویت | priority: "high" یا priority: "normal" صریح |
با نوع اتحاد (remote_notification برای هشدارهای فوری درمقابل background_sync برای همگامسازی غیرفوری) مشخص میشود |
| پست کردن اعلان | برنامه بهطور دستی با NotificationManager.notify() تماس میگیرد |
FCM SDK و GMS Core مستقیماً یا بااستفاده از NotificationResponse پست میکنند |
| بازخوانیهای مشتری | • onMessageReceived(RemoteMessage)• onDeletedMessages() |
• onNotificationReceived(RemoteMessage)• onBackgroundSyncReceived(RemoteMessage)• onDeletedMessages() |
| جمعشدنی | متفاوت؛ تنظیم صریح لازم است | هر دو نوع پیام میتوانند جمعشدنی یا جمعنشدنی باشند (بهطور پیشفرض جمعنشدنی هستند) |
مجاز کردن درخواستهای ارسال AndroidConfigV2
میتوانید همچنان از کدهای دسترسی OAuth 2.0 مشتقشده از حساب سرویس Firebase خود بااستفاده از «اعتبارنامههای پیشفرض برنامه Google» یا Admin SDK استفاده کنید و درخواستهای POST را به نقطه پایانی HTTP v1 messages:send ارسال کنید.
اگر از حساب سرویس Firebase استفاده نمیکنید، حتماً حساب اختصاصیتان را به نقش مدیر Firebase Cloud Messaging API (roles/firebase.messagingAdmin) اختصاص دهید
و هنگام ایجاد کردن کد دسترسی،
دامنه https://www.googleapis.com/auth/firebase.messaging OAuth 2.0 را درخواست کنید:
POST https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send HTTP/1.1
Authorization: Bearer YOUR_OAUTH_ACCESS_TOKEN
Content-Type: application/json
درخواستهای ارسال سرور بهروزرسانی (REST)
برای ارسال درخواست AndroidConfigV2 بااستفاده از REST API، شیء android را در بدنه درخواست با android_v2 جایگزین کنید. در android_v2، پارامترهای رایج (مانند ttl، collapse_key، data، و restricted_package_name) را مشخص کنید و یکی از فیلدهای اتحادیه زیر را ارائه دهید: remote_notification یا background_sync.
ارسال پیام RemoteNotification
برای ارسال اعلان فوری سَمت کاربر، شیء remote_notification و بار مفید توصیهشده notification آن را اضافه کنید. بهطور پیشفرض mutable_content
روی نادرست تنظیم شده است. GMS Core بلافاصله اعلان را بدون اجرای کد برنامه پسزمینه، ارائه و در سینی سیستم پست میکند.
نمونه JSON درخواست HTTP کامل (اعلان ارائهشده خودکار)
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification": {
"title": "FCM Message",
"body": "This is an FCM notification message!"
},
"android_v2": {
"ttl": "3600s",
"remote_notification": {
"mutable_content": false,
"notification": {
"title": "Order update",
"body": "Your order has been shipped!",
"icon": "ic_notification_custom",
"sound": "default",
"tag": "alert_tag_1",
"id": 100
}
}
}
}
}
ارسال RemoteNotification با محتوای تغییرپذیر
اگر برنامه شما باید اعلان را قبلاز نمایش در دستگاه تغییر دهد، mutable_content: true را در remote_notification تنظیم کنید. این
به «هسته سرویسهای تلفن همراه Google» دستور میدهد تا به برنامه کارخواه شما متصل شود و
onNotificationReceived() را فراخوانی کند. این کار زمانی مفید است که بخواهید بارداده رمزگذاریشده سرتاسر را رمزگشایی کنید، چهرهنماهای کاربر را پیوست کنید، یا رشتهها را بومیسازی کنید.
حتماً یک شیء notification را در remote_notification بگنجانید، حتی زمانی که mutable_content برابر با true است. اگر زمان فراخوانی مشتری تمام شود یا از محدودیتهای سرکوب فراتر رود، GMS Core از این شیء notification بهعنوان اعلان بازگشت استفاده میکند.
اگر از پیامهای داده قدیمی v1 مهاجرت میکنید و میخواهید FCM بار داده را به نصبهای قدیمیتر کلاینت v1 بهعنوان یک پیام داده خالص تحویل دهد، use_as_v1_data_message: true را داخل remote_notification تنظیم کنید.
نمونه JSON درخواست اچتیتیپی کامل
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data": {
"encrypted_content": "U2FsdGVkX19vN2m+",
"sender_id": "user_98124"
},
"android_v2": {
"ttl": "3600s",
"remote_notification": {
"mutable_content": true,
"use_as_v1_data_message": true,
"notification": {
"title": "New message",
"body": "You have a new message",
"tag": "chat_alert",
"id": 1001
}
}
}
}
}
ارسال پیام BackgroundSync
برای ارسال پیام غیرفوری برای همگامسازی دادههای پسزمینه، بهروزرسانیهای وضعیت بیصدا، یا بهروزرسانی نشان یا ابزاره برنامه، از شیء background_sync استفاده کنید.
از این پیامها برای پست کردن اعلانهای قابلمشاهده برای کاربر استفاده نکنید، زیرا ممکن است برای بهینهسازی عمر باتری دستگاه، این اعلانها بهصورت دستهای یا با تأخیر ارسال شوند.
نمونه JSON درخواست اچتیتیپی کامل
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data": {
"score": "FETCH_UPDATES",
"sync_action": "FETCH_UPDATES"
},
"android_v2": {
"ttl": "86400s",
"collapse_key": "app_state_sync",
"background_sync": {}
}
}
}
بهروزرسانی تماسهای برگشتی کارخواه Android
برای دریافت پیامهای AndroidConfigV2 در Android، برنامهتان را ارتقا دهید تا از جدیدترین کیت توسعه نرمافزار firebase-messaging استفاده کند. سرویس خود را با پیادهسازی onNotificationReceived() و onBackgroundSyncReceived() بهروز کنید.FirebaseMessagingService
نصب کیت توسعه نرمافزار EAP
درطول «برنامه دسترسی زودرس»، کیت توسعه نرمافزار firebase-messaging نسخه ۲ بهجای توزیع ازطریق مخزن Maven عمومی Google، بهعنوان بایگانی مخزن Maven محلی توزیع میشود.
دایرکتوری
m2repositoryحاویfirebase-messaging:26.1.0-eap01را بااستفاده از یکی از گزینههای زیر به دایرکتوری ریشه پروژه Android خود (<project-root>/m2repository) اضافه کنید:- گزینه الف: بارگیری بایگانی ازپیشساخته: FirebaseMessaging_26.1.0-eap01.zip را بارگیری کنید
و دایرکتوری
m2repositoryرا در دایرکتوری ریشه پروژه Android (<project-root>/m2repository) استخراج کنید. گزینه ب: ساختن از GitHub با Gradle: شاخه
feature/fcm-android-config-v2-eapfirebase/firebase-android-sdkرا شبیهسازی کنید، مخزن Maven محلی را بسازید، و دایرکتوریbuild/m2repositoryتولیدشده را در ریشه پروژه Android خود کپی کنید:git clone --branch feature/fcm-android-config-v2-eap --single-branch \ https://github.com/firebase/firebase-android-sdk.git cd firebase-android-sdk ./gradlew -PprojectsToPublish="firebase-messaging" firebasePublish cp -R build/m2repository /path/to/your/android-project/m2repository
- گزینه الف: بارگیری بایگانی ازپیشساخته: FirebaseMessaging_26.1.0-eap01.zip را بارگیری کنید
و دایرکتوری
در
settings.gradle.kts(یاsettings.gradle) سطح پروژهتان، دایرکتوریm2repositoryمحلی را به بالای بلوکrepositories، بالایgoogle()اضافه کنید:Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url = uri("${rootDir}/m2repository") } google() mavenCentral() } }Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url "${rootDir}/m2repository" } google() mavenCentral() } }در
app/build.gradle.kts(یاapp/build.gradle) سطح ماژول، وابستگیfirebase-messagingرا به26.1.0-eap01بهروز کنید:Kotlin
dependencies { implementation("com.google.firebase:firebase-messaging:26.1.0-eap01") }Groovy
dependencies { implementation 'com.google.firebase:firebase-messaging:26.1.0-eap01' }پروژهتان را با فایلهای Gradle همگامسازی کنید.
مدیریت RemoteNotifications با onNotificationReceived
با AndroidConfigV2، پیامهای RemoteNotification نمایش داده میشود
مگر اینکه mutable_content روی «درست» تنظیم شده باشد یا صریحاً در
onNotificationReceived() بیصدا شده باشند.
وقتی RemoteNotification با mutable_content: true میرسد، GMS Core به برنامه شما متصل میشود و onNotificationReceived() را فراخوانی میکند. روش شما باید
ظرف ۲۰ ثانیه NotificationResponse را برگرداند.
برگرداندن اعلان اصلاحشده
شیء Notification که به NotificationResponse.create ارسال میکنید جایگزین ویژگیهای بار داده بازگشتی remote_notification.notification سرور میشود که در درخواست ارسال تعریف شده است. برای حفظ مقادیر از درخواست ارسال، آنها را از
message.notification (message.getNotification() در Java) بخوانید و درعینحال
اصلاحات دروندستگاهی را اعمال کنید:
Kotlin
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.NotificationResponse
import com.google.firebase.messaging.RemoteMessage
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onNotificationReceived(message: RemoteMessage): NotificationResponse {
val serverNotif = message.notification
val channelId = serverNotif?.channelId ?: "default_channel"
// Keep the server-defined title unchanged, or fall back to default
val title = serverNotif?.title ?: "New message"
// Modify the notification body on-device (for example, decrypting data)
val decryptedBody = decryptPayload(message.data["encrypted_content"])
val builder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(title)
.setContentText(decryptedBody)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
// Return the response for the open-source FCM SDK to post to the Android platform
return NotificationResponse.create("optional_tag", 100, builder.build())
}
}
Java
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import com.google.firebase.messaging.NotificationResponse;
import androidx.core.app.NotificationCompat;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public NotificationResponse onNotificationReceived(RemoteMessage message) {
RemoteMessage.Notification serverNotif = message.getNotification();
String channelId = (serverNotif != null && serverNotif.getChannelId() != null)
? serverNotif.getChannelId()
: "default_channel";
// Keep the server-defined title unchanged, or fall back to default
String title = (serverNotif != null && serverNotif.getTitle() != null)
? serverNotif.getTitle()
: "New message";
// Modify the notification body on-device (for example, decrypting data)
String decryptedBody = decryptPayload(message.getData().get("encrypted_content"));
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(title)
.setContentText(decryptedBody)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true);
// Return the response for the open-source FCM SDK to post to the Android platform
return NotificationResponse.create("optional_tag", 100, builder.build());
}
}
موقوف کردن اعلان
اگر کاربر درحالحاضر صفحه یا گپ مربوطه را فعال کرده باشد، میتوانید با برگرداندن NotificationResponse.suppress()، اعلان را سرکوب کنید:
Kotlin
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ProcessLifecycleOwner
override fun onNotificationReceived(message: RemoteMessage): NotificationResponse {
val chatId = message.data["chat_id"]
val isAppForeground = ProcessLifecycleOwner.get()
.lifecycle
.currentState
.isAtLeast(Lifecycle.State.STARTED)
if (isAppForeground && chatRepository.isConversationActive(chatId)) {
// Suppress notification display because the user is actively viewing this chat
return NotificationResponse.suppress()
}
val builder = buildNotificationForChat(message)
return NotificationResponse.create("chat_tag", 101, builder.build())
}
Java
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.ProcessLifecycleOwner;
@Override
public NotificationResponse onNotificationReceived(RemoteMessage message) {
String chatId = message.getData().get("chat_id");
boolean isAppForeground = ProcessLifecycleOwner.get()
.getLifecycle()
.getCurrentState()
.isAtLeast(Lifecycle.State.STARTED);
if (isAppForeground && chatRepository.isConversationActive(chatId)) {
// Suppress notification display because the user is actively viewing this chat
return NotificationResponse.suppress();
}
NotificationCompat.Builder builder = buildNotificationForChat(message);
return NotificationResponse.create("chat_tag", 101, builder.build());
}
اعلانهای جاریسازی یا لغو هشدارهای قدیمیتر (FcmNotificationManager)
اگر لازم است چند اعلان برای یک فشار ورودی پست کنید، یا اعلان قدیمی را قبلاز نمایش اعلان جدید لغو کنید، از FcmNotificationManager استفاده کنید:
Kotlin
override fun onNotificationReceived(message: RemoteMessage): NotificationResponse {
// Retrieve the scoped manager for this message execution
val manager = getFcmNotificationManager(message)
// 1. Cancel an outdated notification right away
manager.cancelNow("message_tag", 50)
// 2. Post the item notification immediately
val itemNotif = NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("Alex")
.setContentText(message.data["text"])
manager.postNow("item_tag", 51, itemNotif.build())
// 3. Post a group summary notification
val summaryNotif = NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("New Conversations")
.setGroupSummary(true)
manager.postNow("summary_tag", 52, summaryNotif.build())
// 4. Return finished() to complete the streaming workflow
return manager.finished()
}
Java
@Override
public NotificationResponse onNotificationReceived(RemoteMessage message) {
// Retrieve the scoped manager for this message execution
FcmNotificationManager manager = getFcmNotificationManager(message);
// 1. Cancel an outdated notification right away
manager.cancelNow("message_tag", 50);
// 2. Post the item notification immediately
NotificationCompat.Builder itemNotif = new NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("Alex")
.setContentText(message.getData().get("text"));
manager.postNow("item_tag", 51, itemNotif.build());
// 3. Post a group summary notification
NotificationCompat.Builder summaryNotif = new NotificationCompat.Builder(this, "chat_channel")
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("New Conversations")
.setGroupSummary(true);
manager.postNow("summary_tag", 52, summaryNotif.build());
// 4. Return finished() to complete the streaming workflow
return manager.finished();
}
مدیریت پیامهای BackgroundSync بااستفاده از onBackgroundSyncReceived
برای پردازش پیامهای BackgroundSync در Android، از
onBackgroundSyncReceived() استفاده کنید:
Kotlin
override fun onBackgroundSyncReceived(message: RemoteMessage) {
val syncCommand = message.data["sync_action"]
try {
// Perform local database synchronization or cache refresh
AppDataRepository.getInstance(applicationContext).syncWithServer(syncCommand)
} catch (e: Exception) {
Log.e("FCM", "Background sync operation failed", e)
}
// Execution completes -> GMS Core marks the message as handled and unbinds.
}
Java
@Override
public void onBackgroundSyncReceived(RemoteMessage message) {
String syncCommand = message.getData().get("sync_action");
try {
// Perform local database synchronization or cache refresh
AppDataRepository.getInstance(getApplicationContext()).syncWithServer(syncCommand);
} catch (Exception e) {
Log.e("FCM", "Background sync operation failed", e);
}
// Execution completes -> GMS Core marks the message as handled and unbinds.
}
مدیریت حذف پیامهای معلق بااستفاده از onDeletedMessages
در برخی شرایط، مثلاً وقتی دستگاهی برای مدت طولانی به FCM متصل نشده باشد یا وقتی صف سرور پر باشد، ممکن است FCM پیامهای معلقه را قبلاز تحویل حذف کند. در این موارد، لغو کردن
onDeletedMessages():
Kotlin
override fun onDeletedMessages() {
// Perform a full state synchronization with your app server
AppDataRepository.getInstance(applicationContext).scheduleFullSync()
}
Java
@Override
public void onDeletedMessages() {
// Perform a full state synchronization with your app server
AppDataRepository.getInstance(getApplicationContext()).scheduleFullSync();
}
انتقال برنامههای خاص
ارسال اعلانهای سرتاسر رمزگذاریشده (E2EE)
هنگام ارسال اعلان رمزگذاریشده سرتاسر بااستفاده از
RemoteNotification، محتوای اعلان رمزگشاییشده
در برنامه شما و پلاتفرم Android باقی میماند:
- ارسال اعلان تغییرپذیر:
سرور شما
RemoteNotificationرا باmutable_content: true، بار داده رمزگذاریشده درdata، و نسخه پشتیبان رمزگذارینشده عمومیnotificationارسال میکند. «هسته سرویسهای تلفن همراه Google» پیام رمزگذاریشده را به کیت توسعه نرمافزار متنباز FCM درون برنامهتان ارسال میکند. - رمزگشایی و برگرداندن اعلان: کیت توسعه نرمافزار FCM،
onNotificationReceived()را فراخوانی میکند. برنامه شما بار خالص را بهطور محلی رمزگشایی میکند،NotificationAndroid رمزگشاییشده نهایی را میسازد، و آن را بااستفاده ازNotificationResponseیاFcmNotificationManagerبه کیت توسعه نرمافزار FCM متنباز برمیگرداند. - پست کردن در پلاتفرم و گزارش کردن فراداده: کیت توسعه نرمافزار FCM متنباز
اعلان رمزگشاییشده را مستقیماً در API پلاتفرم Android
NotificationManagerپست میکند و فقط فراداده اعلان، مثل شناسه اعلان و مُهر زمان، را برای مشاهدهپذیری تحویل به «هسته سرویسهای تلفن همراه Google» برمیگرداند. محتوای رمزگشاییشده هرگز به «هسته GMS» ارسال نمیشود. - درصورت لزوم، اعلان پشتیبانگیری را پست کنید: فقط اگر برنامهتان نتواند در مهلت ۲۰ ثانیهای پاسخ دهد یا از محدودیتهای سرکوب پسزمینه فراتر رود، GMS Core پشتیبانگیری عمومی
notificationرا مستقیماً در پلاتفرم Android پست میکند.

آشنایی با توقف موقت اعلانها و مهلتها
برای حفظ تحویل قابلاطمینان در سراسر بومسازگان Android، GMS Core
محدودیتهای توقف پردازش و سرکوب اعلان را هنگام رسیدگی به
پیامهای RemoteNotification اعمال میکند:
مهلت پردازش تمام شد
وقتی mutable_content روی true تنظیم شده باشد، روش onNotificationReceived() شما
باید ظرف ۲۰ ثانیه NotificationResponse را برگرداند. اگر
اجرا از این آستانه فراتر رود، فراخوان لغو میشود و GMS Core
بهطور خودکار اعلان بازگشتی را که از محموله داده
remote_notification.notification ارائه شده است پست میکند.
نرخ توقف اعلان
ازآنجاییکه پیامهای RemoteNotification محدودیتهای Doze را دور میزنند تا فوراً به کاربران هشدار دهند و بدون تأخیر تحویل داده میشوند، انتظار میرود برنامهها اعلانهای پیامهای RemoteNotification دریافتی را نمایش دهند.
هر برنامه مجاز است تا ۲۵٪ از ترافیک RemoteNotification خود را هنگام اجرا در پسزمینه سرکوب کند. اگر نرخ سرکوب برنامه از ۲۵٪ فراتر رود، GMS Core بهطور خودکار اعلان جایگزینی را که از بار داده remote_notification.notification ارائه شده است ارائه و پست میکند.
محدودیتهایی که هنگام فعال بودن برنامه در پیشزمینه اعمال میشوند در این آستانه محاسبه نمیشوند. برنامههایی که اجازه استفاده نامحدود در پسزمینه به آنها اعطا شده است نیز از محدودیتهای سرکوب پسزمینه معاف هستند.