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

يتطلب عملاء "المراسلة عبر السحابة الإلكترونية من Firebase" أجهزة تعمل بالإصدار 4.4 من نظام التشغيل Android أو إصدار أحدث تم تثبيت تطبيق "متجر Google Play" عليه أيضًا، أو محاكيًا يعمل بالإصدار 4.4 من نظام التشغيل 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 لواجهة برمجة التطبيقات) والإصدارات الأحدث، قنوات الإشعارات متوافقة ويُنصح بها. توفّر ميزة "المراسلة عبر السحابة الإلكترونية من Firebase" قناة إشعارات تلقائية تتضمّن الإعدادات الأساسية. إذا كنت تفضّل إنشاء قناتك التلقائية واستخدامها، عليك ضبط default_notification_channel_id على رقم تعريف عنصر قناة الإشعارات كما هو موضّح، وستستخدم خدمة "المراسلة عبر السحابة الإلكترونية من Firebase" هذه القيمة في حال لم تضبط الرسائل الواردة قناة إشعار بشكل صريح. لمزيد من المعلومات، يمكنك الاطّلاع على إدارة قنوات الإشعارات.
  • <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 أو الإصدارات الأحدث والتي تستخدم إشعارات "المراسلة عبر السحابة الإلكترونية من Firebase".

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

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

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

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

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

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

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

عند إنشاء رمز مميَّز لتسجيل خدمة "المراسلة عبر السحابة الإلكترونية من Firebase"، تحمِّل المكتبة بيانات المعرّف وبيانات الضبط إلى 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 للمشرف.