Android ऐप्लिकेशन में मैसेज पाना

Firebase सूचनाएं, सूचना पाने वाले ऐप्लिकेशन की फ़ोरग्राउंड/बैकग्राउंड स्थिति के आधार पर अलग-अलग तरीके से काम करती हैं. अगर आपको फ़ोरग्राउंड में चल रहे ऐप्लिकेशन को सूचना वाले मैसेज या डेटा मैसेज भेजने हैं, तो आपको onMessageReceived कॉलबैक को हैंडल करने के लिए कोड लिखना होगा. सूचना और डेटा मैसेज के बीच के अंतर के बारे में जानने के लिए, मैसेज के टाइप लेख पढ़ें.

मैसेज मैनेज करना

मैसेज पाने के लिए, ऐसी सेवा का इस्तेमाल करें जो FirebaseMessagingService को एक्सटेंड करती हो. आपकी सेवा को onMessageReceived और onDeletedMessages कॉलबैक को ओवरराइड करना चाहिए.

मैसेज को हैंडल करने के लिए, 20 सेकंड से कम समय मिल सकता है. ऐसा onMessageReceived को कॉल करने से पहले होने वाली देरी की वजह से होता है. जैसे, ओएस में देरी, ऐप्लिकेशन के स्टार्टअप में लगने वाला समय, मुख्य थ्रेड का अन्य कार्रवाइयों से ब्लॉक होना या पिछले onMessageReceived कॉल में ज़्यादा समय लगना. इसके बाद, ओएस के अलग-अलग फ़ंक्शन काम करने लगते हैं. जैसे, Android की प्रोसेस किलिंग या Android O की बैकग्राउंड में ऐप्लिकेशन चलाने की सीमाएं. इनकी वजह से, आपको काम पूरा करने में समस्या आ सकती है.

onMessageReceived की सुविधा, ज़्यादातर तरह के मैसेज के लिए उपलब्ध है. हालांकि, इन मैसेज के लिए यह सुविधा उपलब्ध नहीं है:

  • ऐप्लिकेशन के बैकग्राउंड में होने पर डिलीवर किए गए सूचना वाले मैसेज. इस मामले में, सूचना को डिवाइस की सिस्टम ट्रे में डिलीवर किया जाता है. जब कोई उपयोगकर्ता किसी सूचना पर टैप करता है, तो ऐप्लिकेशन लॉन्चर डिफ़ॉल्ट रूप से खुल जाता है.

  • बैकग्राउंड में सूचना और डेटा पेलोड, दोनों वाले मैसेज मिलने पर. इस मामले में, सूचना को डिवाइस की सिस्टम ट्रे में भेजा जाता है. साथ ही, डेटा पेलोड को आपके लॉन्चर ऐक्टिविटी के इंटेंट के एक्स्ट्रा में भेजा जाता है.

सारांश में:

ऐप्लिकेशन का स्टेटस सूचना डेटा दोनों
फ़ोरग्राउंड onMessageReceived onMessageReceived onMessageReceived
बैकग्राउंड सिस्टम ट्रे onMessageReceived सूचना: सिस्टम ट्रे
डेटा: इंटेंट के एक्स्ट्रा में.
मैसेज टाइप के बारे में ज़्यादा जानने के लिए, सूचनाएं और डेटा मैसेज लेख पढ़ें.

ऐप्लिकेशन मेनिफ़ेस्ट में बदलाव करना

FirebaseMessagingService का इस्तेमाल करने के लिए, आपको अपने ऐप्लिकेशन के मेनिफ़ेस्ट में यह जानकारी जोड़नी होगी:

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

इसके अलावा, हमारा सुझाव है कि सूचनाओं को अपनी पसंद के मुताबिक बनाने के लिए, डिफ़ॉल्ट वैल्यू सेट करें. आपके पास कस्टम डिफ़ॉल्ट आइकॉन और कस्टम डिफ़ॉल्ट रंग तय करने का विकल्प होता है. ये आइकॉन और रंग तब लागू होते हैं, जब सूचना के पेलोड में बराबर वैल्यू सेट नहीं की जाती हैं.

कस्टम डिफ़ॉल्ट आइकॉन और कस्टम रंग सेट करने के लिए, इन लाइनों को application टैग में जोड़ें:

<!-- 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" />

Android, इनके लिए कस्टम डिफ़ॉल्ट आइकॉन दिखाता है

Android, इन कामों के लिए पसंद के मुताबिक सेट किए गए डिफ़ॉल्ट रंग का इस्तेमाल करता है

  • सूचनाएं कंपोज़ करने की सुविधा से भेजे गए सभी सूचना वाले मैसेज.
  • सूचना देने वाला ऐसा कोई भी मैसेज जिसमें सूचना के पेलोड में रंग साफ़ तौर पर सेट नहीं किया गया है.

अगर कस्टम डिफ़ॉल्ट आइकॉन सेट नहीं किया गया है और सूचना के पेलोड में कोई आइकॉन सेट नहीं किया गया है, तो Android, ऐप्लिकेशन का आइकॉन दिखाता है. यह आइकॉन सफ़ेद रंग में रेंडर किया जाता है.

onMessageReceived को बदलें

FirebaseMessagingService.onMessageReceived तरीके को बदलकर, आपको मिले RemoteMessage ऑब्जेक्ट के आधार पर कार्रवाइयां की जा सकती हैं. साथ ही, मैसेज का डेटा पाया जा सकता है:

Kotlin

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: ${remoteMessage.from}")

    // Check if message contains a data payload.
    if (remoteMessage.data.isNotEmpty()) {
        Log.d(TAG, "Message data payload: ${remoteMessage.data}")

        // Check if data needs to be processed by long running job
        if (needsToBeScheduled()) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob()
        } else {
            // Handle message within 10 seconds
            handleNow()
        }
    }

    // Check if message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Java

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

onDeletedMessages को बदलें

कुछ मामलों में, FCM मैसेज नहीं भेज सकता. ऐसा तब होता है, जब किसी डिवाइस पर आपका ऐप्लिकेशन कनेक्ट होता है और उस समय 100 से ज़्यादा मैसेज पेंडिंग होते हैं. इसके अलावा, ऐसा तब भी हो सकता है, जब डिवाइस एक महीने से ज़्यादा समय से FCM से कनेक्ट न हुआ हो. इन मामलों में, आपको FirebaseMessagingService.onDeletedMessages() पर कॉलबैक मिल सकता है जब ऐप्लिकेशन इंस्टेंस को यह कॉलबैक मिलता है, तो उसे आपके ऐप्लिकेशन सर्वर के साथ पूरा सिंक करना चाहिए. अगर आपने पिछले चार हफ़्तों में उस डिवाइस पर मौजूद ऐप्लिकेशन से कोई मैसेज नहीं भेजा है, तो FCM, onDeletedMessages() को कॉल नहीं करेगा.

बैकग्राउंड में चल रहे ऐप्लिकेशन में सूचनाएं मैनेज करना

जब आपका ऐप्लिकेशन बैकग्राउंड में होता है, तो Android सूचना वाले मैसेज को सिस्टम ट्रे में भेजता है. कोई उपयोगकर्ता जब सूचना पर टैप करता है, तो ऐप्लिकेशन लॉन्चर डिफ़ॉल्ट रूप से खुल जाता है.

इसमें ऐसे मैसेज शामिल हैं जिनमें सूचना और डेटा पेलोड, दोनों शामिल होते हैं. साथ ही, इसमें Notifications console से भेजे गए सभी मैसेज भी शामिल होते हैं. इन मामलों में, सूचना को डिवाइस की सिस्टम ट्रे में डिलीवर किया जाता है. साथ ही, डेटा पेलोड को आपके लॉन्चर ऐक्टिविटी के इंटेंट के एक्स्ट्रा में डिलीवर किया जाता है.

अपने ऐप्लिकेशन पर मैसेज डिलीवर होने की जानकारी पाने के लिए, FCM रिपोर्टिंग डैशबोर्ड देखें. यह डैशबोर्ड, Apple और Android डिवाइसों पर भेजे गए और खोले गए मैसेज की संख्या रिकॉर्ड करता है. साथ ही, Android ऐप्लिकेशन के लिए "इंप्रेशन" (उपयोगकर्ताओं को दिखने वाली सूचनाएं) का डेटा भी रिकॉर्ड करता है.

डायरेक्ट बूट मोड में FCM मैसेज पाना

जिन डेवलपर को डिवाइस अनलॉक होने से पहले भी ऐप्लिकेशन को FCM मैसेज भेजने हैं वे किसी Android ऐप्लिकेशन को यह अनुमति दे सकते हैं कि डिवाइस डायरेक्ट बूट मोड में होने पर भी उसे मैसेज मिलें. उदाहरण के लिए, हो सकता है कि आपको अपने ऐप्लिकेशन के उपयोगकर्ताओं को, डिवाइस के लॉक होने पर भी अलार्म की सूचनाएं भेजनी हों.

इस इस्तेमाल के उदाहरण को बनाते समय, डायरेक्ट बूट मोड के लिए सबसे सही तरीके और पाबंदियों का पालन करें. डायरेक्ट बूट की सुविधा चालू होने पर, मैसेज की विज़िबिलिटी पर खास तौर पर ध्यान देना ज़रूरी है. डिवाइस का ऐक्सेस रखने वाला कोई भी व्यक्ति, उपयोगकर्ता के क्रेडेंशियल डाले बिना इन मैसेज को देख सकता है.

ज़रूरी शर्तें

  • डिवाइस को डायरेक्ट बूट मोड के लिए सेट अप किया गया हो.
  • डिवाइस पर Google Play services का नया वर्शन (19.0.54 या उसके बाद का वर्शन) इंस्टॉल होना चाहिए.
  • FCM मैसेज पाने के लिए, ऐप्लिकेशन को FCM SDK (com.google.firebase:firebase-messaging) का इस्तेमाल करना होगा.

अपने ऐप्लिकेशन में डायरेक्ट बूट मोड में मैसेज हैंडल करने की सुविधा चालू करना

  1. ऐप्लिकेशन-लेवल की Gradle फ़ाइल में, FCM डायरेक्ट बूट सपोर्ट लाइब्रेरी की डिपेंडेंसी जोड़ें:

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
    
  2. ऐप्लिकेशन के मेनिफ़ेस्ट में android:directBootAware="true" एट्रिब्यूट जोड़कर, ऐप्लिकेशन को FirebaseMessagingService डायरेक्ट बूट के बारे में जानकारी दें:

    <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false"
        android:directBootAware="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

यह पक्का करना ज़रूरी है कि यह FirebaseMessagingService डायरेक्ट बूट मोड में चल सके. इन ज़रूरी शर्तों को पूरा करें:

  • डायरेक्ट बूट मोड में चलने के दौरान, सेवा को क्रेडेंशियल से सुरक्षित किए गए स्टोरेज को ऐक्सेस नहीं करना चाहिए.
  • डायरेक्ट बूट मोड में चलने के दौरान, सेवा को ऐसे कॉम्पोनेंट इस्तेमाल करने की कोशिश नहीं करनी चाहिए जिन्हें डायरेक्ट बूट मोड के बारे में जानकारी रखने वाले कॉम्पोनेंट के तौर पर मार्क नहीं किया गया है. जैसे, Activities, BroadcastReceivers या अन्य Services.
  • सेवा में इस्तेमाल होने वाली किसी भी लाइब्रेरी को, क्रेडेंशियल से सुरक्षित किए गए स्टोरेज को ऐक्सेस नहीं करना चाहिए. साथ ही, डायरेक्ट बूट मोड में चलते समय, non-directBootAware कॉम्पोनेंट को कॉल नहीं करना चाहिए. इसका मतलब है कि ऐप्लिकेशन में इस्तेमाल की जा रही किसी भी लाइब्रेरी को, डायरेक्ट बूट मोड के बारे में पता होना चाहिए. इसके अलावा, ऐप्लिकेशन को यह भी जांच करनी होगी कि वह डायरेक्ट बूट मोड में चल रहा है या नहीं. अगर ऐप्लिकेशन डायरेक्ट बूट मोड में चल रहा है, तो उसे लाइब्रेरी को कॉल नहीं करना चाहिए. उदाहरण के लिए, Firebase SDK टूल डायरेक्ट बूट मोड के साथ काम करते हैं. इन्हें डायरेक्ट बूट मोड में ऐप्लिकेशन क्रैश किए बिना ऐप्लिकेशन में शामिल किया जा सकता है. हालांकि, कई Firebase API, डायरेक्ट बूट मोड में कॉल किए जाने की सुविधा के साथ काम नहीं करते.
  • अगर ऐप्लिकेशन, कस्टम Application का इस्तेमाल कर रहा है, तो Application को भी डायरेक्ट बूट के बारे में पता होना चाहिए. डायरेक्ट बूट मोड में, क्रेडेंशियल से सुरक्षित स्टोरेज को ऐक्सेस नहीं किया जा सकता.

डायरेक्ट बूट मोड में डिवाइसों को मैसेज भेजने के बारे में जानकारी पाने के लिए, डायरेक्ट बूट मोड में मैसेज भेजना लेख पढ़ें.