إعداد تطبيق عميل "المراسلة عبر السحابة الإلكترونية من Firebase" على نظام التشغيل Android

تتطلّب برامج FCM توفّر أجهزة تعمل بالإصدار 5.0 من نظام التشغيل Android أو الإصدارات الأحدث، مع تثبيت تطبيق "متجر Google Play" عليها، أو محاكي يعمل بالإصدار 5.0 من نظام التشغيل Android مع توفّر واجهات Google APIs. يُرجى العِلم أنّه لا يقتصر نشر تطبيقات Android على "متجر Google Play".

إعداد حزمة تطوير البرامج (SDK)

يتناول هذا القسم المهام التي ربما تكون قد أكملتها إذا سبق لك تفعيل ميزات أخرى من Firebase لتطبيقك. إذا لم يسبق لك إجراء ذلك، أضِف Firebase إلى مشروع Android الخاص بك.

تعديل بيان تطبيقك

أضِف ما يلي إلى بيان تطبيقك:

  • خدمة توسّع نطاق FirebaseMessagingService. ويكون ذلك مطلوبًا إذا كنت تريد تنفيذ أي إجراءات أخرى على الرسائل غير تلقّي الإشعارات على التطبيقات التي تعمل في الخلفية. لتلقّي الإشعارات في التطبيقات التي تعمل في المقدّمة، ولتلقّي حمولة البيانات وما إلى ذلك، عليك توسيع نطاق هذه الخدمة.
  • <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
  • (اختياري) ضمن مكوّن التطبيق، عناصر البيانات الوصفية لضبط رمز ولون تلقائيين للإشعارات يستخدم نظام التشغيل Android هذه القيم عندما لا تحدّد الرسائل الواردة الرمز أو اللون بشكل صريح.
  • <!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
         See README(https://goo.gl/l4GJaQ) for more. -->
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_stat_ic_notification" />
    <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
         notification message. See README(https://goo.gl/6BKBk7) for more. -->
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />
  • (اختياري) بدءًا من الإصدار 8.0 من نظام التشغيل Android (المستوى 26 من واجهة برمجة التطبيقات) والإصدارات الأحدث، تتوفّر قنوات الإشعارات ويُنصح باستخدامها. توفّر FCM قناة إشعارات تلقائية تتضمّن إعدادات أساسية. إذا كنت تفضّل إنشاء واستخدام قناتك التلقائية، اضبط default_notification_channel_id على رقم تعريف عنصر قناة الإشعارات كما هو موضّح، وستستخدم FCM هذه القيمة عندما لا تحدّد الرسائل الواردة قناة إشعارات بشكل صريح. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة إدارة قنوات الإشعارات.
  • <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />

طلب إذن إرسال الإشعارات أثناء التشغيل على الإصدار 13 من نظام التشغيل Android والإصدارات الأحدث

يقدِّم نظام التشغيل Android 13 إذنًا جديدًا في وقت التشغيل لعرض الإشعارات. يؤثر ذلك في جميع التطبيقات التي تعمل على نظام التشغيل Android 13 أو الإصدارات الأحدث والتي تستخدم الإشعارات FCM.

تتضمّن حزمة تطوير البرامج (SDK) FCM (الإصدار 23.0.6 أو إصدار أحدث) تلقائيًا الإذن POST_NOTIFICATIONS المحدّد في البيان. ومع ذلك، سيحتاج تطبيقك أيضًا إلى طلب إصدار وقت التشغيل من هذا الإذن من خلال الثابت android.permission.POST_NOTIFICATIONS. ولن يُسمح لتطبيقك بعرض الإشعارات إلى أن يمنح المستخدم هذا الإذن.

لطلب إذن التشغيل الجديد، اتّبِع الخطوات التالية:

Kotlin

// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
    if (isGranted) {
        // FCM SDK (and your app) can post notifications.
    } else {
        // TODO: Inform user that that your app will not show notifications.
    }
}

private fun askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
            PackageManager.PERMISSION_GRANTED
        ) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
        }
    }
}

Java

// Declare the launcher at the top of your Activity/Fragment:
private final ActivityResultLauncher<String> requestPermissionLauncher =
        registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
            if (isGranted) {
                // FCM SDK (and your app) can post notifications.
            } else {
                // TODO: Inform user that that your app will not show notifications.
            }
        });

private void askNotificationPermission() {
    // This is only necessary for API level >= 33 (TIRAMISU)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
                PackageManager.PERMISSION_GRANTED) {
            // FCM SDK (and your app) can post notifications.
        } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
            // TODO: display an educational UI explaining to the user the features that will be enabled
            //       by them granting the POST_NOTIFICATION permission. This UI should provide the user
            //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
            //       If the user selects "No thanks," allow the user to continue without notifications.
        } else {
            // Directly ask for the permission
            requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
        }
    }
}

بشكل عام، عليك عرض واجهة مستخدم توضّح للمستخدم الميزات التي سيتم تفعيلها إذا منح أذونات للتطبيق بنشر الإشعارات. يجب أن توفّر واجهة المستخدم هذه خيارات للمستخدم للموافقة أو الرفض، مثل زري حسنًا ولا شكرًا. إذا نقر المستخدم على حسنًا، اطلب الإذن مباشرةً. إذا نقر المستخدم على لا، شكرًا، اسمح له بالمتابعة بدون إشعارات.

راجِع إذن التشغيل الخاص بالإشعارات للاطّلاع على مزيد من أفضل الممارسات بشأن الحالات التي يجب أن يطلب فيها تطبيقك الإذن POST_NOTIFICATIONS من المستخدم.

أذونات الإشعارات للتطبيقات التي تستهدف الإصدار 12L من Android (المستوى 32 لواجهة برمجة التطبيقات) أو الإصدارات الأقدم

يطلب نظام التشغيل Android تلقائيًا من المستخدم الإذن في المرة الأولى التي ينشئ فيها تطبيقك قناة إشعارات، طالما أنّ التطبيق يعمل في المقدّمة. ومع ذلك، هناك بعض التحذيرات المهمة بشأن توقيت إنشاء القناة وطلبات الأذونات:

  • إذا أنشأ تطبيقك قناة الإشعارات الأولى أثناء تشغيله في الخلفية (وهو ما تفعله حزمة تطوير البرامج (SDK) FCM عند تلقّي إشعار FCM)، لن يسمح نظام التشغيل Android بعرض الإشعار ولن يطلب من المستخدم منح إذن الإشعارات إلا في المرة التالية التي يتم فيها فتح تطبيقك. وهذا يعني أنّه سيتم فقدان أي إشعارات تم تلقّيها قبل فتح تطبيقك وقبول المستخدم للإذن.
  • ننصحك بشدة بتحديث تطبيقك لاستهداف الإصدار 13 من نظام التشغيل Android أو الإصدارات الأحدث للاستفادة من واجهات برمجة التطبيقات المتوفّرة على النظام الأساسي لطلب الإذن. إذا لم يكن ذلك ممكنًا، يجب أن ينشئ تطبيقك قنوات إشعارات قبل إرسال أي إشعارات إلى التطبيق من أجل عرض مربّع حوار طلب الإذن بتلقّي الإشعارات والتأكّد من عدم فقدان أي إشعارات. يمكنك الاطّلاع على أفضل الممارسات المتعلّقة بأذونات الإشعارات للحصول على مزيد من المعلومات.

اختياري: إزالة إذن POST_NOTIFICATIONS

تتضمّن حزمة تطوير البرامج (SDK) الخاصة بـ "FCM" الإذن POST_NOTIFICATIONS تلقائيًا. إذا كان تطبيقك لا يستخدم رسائل الإشعارات (سواء من خلال FCMالإشعارات أو من خلال حزمة SDK أخرى أو من خلال نشرها مباشرةً من تطبيقك) وكنت لا تريد أن يتضمّن تطبيقك الإذن، يمكنك إزالته باستخدام العلامة remove في أداة دمج ملفات البيان. يُرجى العِلم أنّ إزالة هذا الإذن تمنع عرض جميع الإشعارات، وليس فقط إشعارات FCM. أضِف ما يلي إلى ملف البيان الخاص بتطبيقك:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/>

الوصول إلى الرمز المميز لتسجيل الجهاز

عند بدء تشغيل تطبيقك لأول مرة، تنشئ حزمة تطوير البرامج (SDK) الخاصة بخدمة FCM رمز تسجيل لنسخة تطبيق العميل. إذا أردت استهداف أجهزة فردية أو إنشاء مجموعات أجهزة، عليك الوصول إلى هذا الرمز المميّز من خلال توسيع FirebaseMessagingService وتجاوز onNewToken.

يوضّح هذا القسم كيفية استرداد الرمز المميز وكيفية مراقبة التغييرات التي تطرأ عليه. بما أنّه يمكن تغيير الرمز المميّز بعد بدء التشغيل الأوّلي، ننصحك بشدة باسترداد أحدث رمز مميّز معدَّل للتسجيل.

قد يتغيّر رمز التسجيل في الحالات التالية:

  • تمت استعادة التطبيق على جهاز جديد
  • يلغي المستخدم تثبيت التطبيق أو يعيد تثبيته
  • يمحو المستخدم بيانات التطبيق.

استرداد رمز التسجيل الحالي

عند الحاجة إلى استرداد الرمز المميّز الحالي، اتّصِل بالدالة FirebaseMessaging.getInstance().getToken():

Kotlin

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
    val token = task.result

    // Log and toast
    val msg = getString(R.string.msg_token_fmt, token)
    Log.d(TAG, msg)
    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})

Java

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

مراقبة إنشاء الرموز المميزة

يتم تشغيل الدالة onNewToken عند إنشاء رمز مميز جديد.

Kotlin

/**
 * Called if the FCM registration token is updated. This may occur if the security of
 * the previous token had been compromised. Note that this is called when the
 * FCM registration token is initially generated so this is where you would retrieve the token.
 */
override fun onNewToken(token: String) {
    Log.d(TAG, "Refreshed token: $token")

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token)
}

Java

/**
 * There are two scenarios when onNewToken is called:
 * 1) When a new token is generated on initial app startup
 * 2) Whenever an existing token is changed
 * Under #2, there are three scenarios when the existing token is changed:
 * A) App is restored to a new device
 * B) User uninstalls/reinstalls the app
 * C) User clears app data
 */
@Override
public void onNewToken(@NonNull String token) {
    Log.d(TAG, "Refreshed token: " + token);

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // FCM registration token to your app server.
    sendRegistrationToServer(token);
}

بعد الحصول على الرمز المميّز، يمكنك إرساله إلى خادم تطبيقك وتخزينه باستخدام طريقتك المفضّلة.

التحقّق من توفّر "خدمات Google Play"

يجب أن تتحقّق التطبيقات التي تعتمد على حزمة تطوير البرامج (SDK) الخاصة بخدمات Play دائمًا من توفّر حزمة APK متوافقة من &quot;خدمات Google Play&quot; على الجهاز قبل الوصول إلى ميزات &quot;خدمات Google Play&quot;. يُنصح بتنفيذ ذلك في موضعَين: في طريقة onCreate() الخاصة بالنشاط الرئيسي، وفي طريقة onResume() الخاصة به. يضمن التحقّق في onCreate() عدم إمكانية استخدام التطبيق بدون إكمال عملية التحقّق بنجاح. يضمن إجراء عملية تسجيل الدخول onResume() أنّه إذا عاد المستخدم إلى التطبيق قيد التشغيل من خلال وسيلة أخرى، مثل زر الرجوع، سيتم تنفيذ عملية التحقّق.

إذا لم يكن الجهاز يتضمّن إصدارًا متوافقًا من "خدمات Google Play"، يمكن لتطبيقك طلب GoogleApiAvailability.makeGooglePlayServicesAvailable() للسماح للمستخدمين بتنزيل "خدمات Google Play" من "متجر Play".

منع بدء التشغيل التلقائي

عند إنشاء رمز تسجيل FCM، تحمّل المكتبة المعرّف وبيانات الإعداد إلى Firebase. إذا كنت تفضّل منع إنشاء الرموز المميزة تلقائيًا، عليك إيقاف جمع البيانات في "إحصاءات Google" وإيقاف الإعداد التلقائي لخدمة FCM (يجب إيقاف كليهما) عن طريق إضافة قيم البيانات الوصفية التالية إلى 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، عليك إجراء عملية استدعاء في وقت التشغيل:

Kotlin

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

لإعادة تفعيل عملية جمع البيانات في &quot;إحصاءات Google&quot;، استدعِ طريقة setAnalyticsCollectionEnabled() التابعة لفئة FirebaseAnalytics. على سبيل المثال:

setAnalyticsCollectionEnabled(true);

تظل هذه القيم محفوظة عند إعادة تشغيل التطبيق بعد ضبطها.

الخطوات التالية

بعد إعداد تطبيق العميل، يمكنك البدء في إرسال الرسائل إلى الأجهزة باستخدام أداة إنشاء الإشعارات. يتم توضيح هذه الوظيفة في نموذج التشغيل السريع، والذي يمكنك تنزيله وتشغيله ومراجعته.

لإضافة سلوكيات أخرى أكثر تقدّمًا إلى تطبيقك، يمكنك تعريف فلتر أهداف وتنفيذ نشاط للرد على الرسائل الواردة. للحصول على التفاصيل، يُرجى الاطّلاع على أدلة إرسال الرسائل من خادم التطبيق:

يُرجى العِلم أنّه للاستفادة من هذه الميزات، يجب توفير تنفيذ على الخادم وبروتوكولات الخادم (HTTP أو XMPP)، أو تنفيذ حزمة SDK لوحدة تحكّم المشرف.