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

تتطلّب تطبيقات FCM أجهزة تعمل بالإصدار 5.0 من Android أو إصدار أحدث ومزوّدة أيضًا بتطبيق "متجر Google Play"، أو جهاز محاكاة يعمل بالإصدار 5.0 من Android مع واجهات برمجة تطبيقات Google. تجدر الإشارة إلى أنّه يمكنك نشر تطبيقات 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+KTX

// 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+KTX

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+KTX

/**
 * 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 متوافقة لخدمات Google Play في الجهاز قبل الوصول إلى ميزات "خدمات Google Play". ننصح بإجراء ذلك في مكانَين: في طريقة onCreate() للنشاط الرئيسي وفي طريقة onResume(). يضمن التحقّق في onCreate() عدم إمكانية استخدام التطبيق بدون إجراء عملية تحقق ناجحة. يضمن التحقّق في onResume() أنّه في حال عودة المستخدم إلى التطبيق الذي يعمل من خلال بعض الوسائل الأخرى، مثل الزر الرجوع، سيظلّ التحقّق جاريًا.

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

منع الإعداد التلقائي

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

لإعادة تفعيل ميزة "الإعداد التلقائي" في إطار عمل Firebase، يمكنك إجراء مكالمة وقت التشغيل:

Kotlin+KTX

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

لإعادة تفعيل جمع البيانات في "إحصاءات Google"، استخدِم الأسلوب setAnalyticsCollectionEnabled() لفئة FirebaseAnalytics. على سبيل المثال:

setAnalyticsCollectionEnabled(true);

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

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

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

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

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