Firebase onMessageReceived जब पृष्ठभूमि में app नहीं कहा जाता है


232

मैं फायरबेस के साथ काम कर रहा हूं और ऐप को बैकग्राउंड में रहते हुए अपने सर्वर से अपने ऐप को नोटिफिकेशन भेज रहा हूं। अधिसूचना को सफलतापूर्वक भेजा जाता है, यह डिवाइस के सूचना केंद्र पर भी दिखाई देता है, लेकिन जब अधिसूचना दिखाई देती है या यहां तक ​​कि अगर मैं इस पर क्लिक करता हूं, तो मेरे FCMessagingService के अंदर ऑनमैसेजेज विधि कभी नहीं कहा जाता है।

जब मैंने अपने ऐप को अग्रभूमि में परीक्षण किया, तब ऑनमैसेजेज विधि को बुलाया गया और सब कुछ ठीक रहा। समस्या तब होती है जब ऐप पृष्ठभूमि में चल रहा होता है।

क्या यह इच्छित व्यवहार है, या कोई ऐसा तरीका है जिससे मैं इसे ठीक कर सकता हूं?

यहाँ मेरा FBMessagingService है:

import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class FBMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.i("PVL", "MESSAGE RECEIVED!!");
        if (remoteMessage.getNotification().getBody() != null) {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody());
        } else {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message"));
        }
    }
}

Json body के अलावा, आपका onTokenRefresh कोड कहां है? क्या आपने Android सेटअप पूरा किया है ?
काटो

4
नोटिफिकेशन के json body से क्या तात्पर्य है? इसके अलावा, मेरा OnTokenRefresh कोड मेरे FirebaseInstanceID सेवा के अंदर है।
सायोजनोस

क्या आप जो सैंपल पेलोड भेज रहे हैं उसे पोस्ट कर सकते हैं?
एएल।


आप इस सूत्र को भी देख सकते हैं stackoverflow.com/questions/39046270/…
Md। सज्जादुल करीम

जवाबों:


144

यह इरादा के अनुसार काम कर रहा है, सूचना संदेशों को आपके ऑनमैसेजेज पर कॉलबैक पर पहुंचाया जाता है, जब आपका ऐप अग्रभूमि में होता है। अगर आपका ऐप बैकग्राउंड में है या बंद है तो नोटिफिकेशन सेंटर में एक नोटिफिकेशन मैसेज दिखाया जाता है, और उस मैसेज का कोई भी डेटा उस मंशा को पास कर दिया जाता है, जो नोटिफिकेशन पर यूजर के टैप करने के परिणामस्वरूप लॉन्च होता है।

उपयोगकर्ता द्वारा अधिसूचना टैप किए जाने पर जो इरादा लॉन्च किया जाना चाहिए, उसे इंगित करने के लिए आप एक click_action निर्दिष्ट कर सकते हैं। यदि कोई क्लिक_एक्शन निर्दिष्ट नहीं किया जाता है, तो मुख्य गतिविधि का उपयोग किया जाता है।

जब इरादा लॉन्च किया जाता है तो आप इसका उपयोग कर सकते हैं

getIntent().getExtras();

एक सेट प्राप्त करने के लिए जिसमें अधिसूचना संदेश के साथ भेजा गया कोई भी डेटा शामिल होगा।

अधिसूचना संदेश पर अधिक के लिए डॉक्स देखें ।


6
click_actionजब मैं Firebase Notification Console का उपयोग कर रहा हूं , तब सेट करने का कोई तरीका है ?
एनआईआई लारिया

6
ठीक है, लेकिन क्या होगा अगर ऐप को मार दिया जाए (कोई अग्रभूमि या पृष्ठभूमि नहीं)?
मीकलू

3
लेकिन उपयोगकर्ता को निष्क्रिय करने की अधिसूचना को कैसे निष्क्रिय करें? क्योंकि यदि उपयोगकर्ता इसे छोड़ देता है, तो इसका मतलब है कि सभी डेटा को छोड़ दिया जाएगा ... सही?
एलेक्सी टिमोशेंको

4
सही बात! इसलिए एंड्रॉइड पर अधिसूचना संदेश भेजते समय, साथ वाला डेटा ऐसा डेटा होना चाहिए जो अधिसूचना अनुभव को बढ़ा रहा हो। यह ऐप महत्वपूर्ण डेटा नहीं होना चाहिए, डेटा के लिए डेटा संदेशों का उपयोग करें जो उपयोगकर्ता को अधिसूचना को खारिज कर देता है, भले ही आवेदन की आवश्यकता हो।
आर्थर थॉम्पसन

3
यह पूरी तरह सही नहीं है। यदि संदेश में केवल डेटा होता है और नोटिफिकेशन पेलोड नहीं है, तो संदेश हमेशा ऑन-प्रिमाइसेज पर डिलीवर किया जाएगा, यदि ऐप अग्रभूमि में है या नहीं।
जैकसोफ 1re

125

notificationअपने सर्वर अनुरोध से फ़ील्ड को पूरी तरह से हटा देंकेवलdata भेजें और इसे संभाल लें onMessageReceived()अन्यथा onMessageReceived()जब ऐप पृष्ठभूमि में होगा या मारा जाएगा तो आपका ट्रिगर नहीं होगा।

"priority": "high"अपने सूचना अनुरोध में फ़ील्ड शामिल करना न भूलें । प्रलेखन के अनुसार: डेटा संदेश एक सामान्य प्राथमिकता के साथ भेजे जाते हैं, इस प्रकार वे तुरंत नहीं पहुंचेंगे; यह भी समस्या हो सकती है।

यहाँ मैं सर्वर से भेज रहा हूँ

{
  "data":{
    "id": 1,
    "missedRequests": 5
    "addAnyDataHere": 123
  },
  "to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......",
  "priority": "high"
}

तो आप अपना डेटा onMessageReceived(RemoteMessage message)इस तरह प्राप्त कर सकते हैं .... मान लें कि मुझे आईडी प्राप्त करना है

Object obj = message.getData().get("id");
        if (obj != null) {
            int id = Integer.valueOf(obj.toString());
        }

9
मैंने पाया कि यदि मैं केवल डेटा संदेश भेजता हूं, तो कार्य प्रबंधक से हटाए गए एप्लिकेशन को सूचना नहीं मिल पाएगी। क्या यह एक इच्छित व्यवहार है?
प्रभजोत सिंह

2
यह मेरे लिए पृष्ठभूमि में संदेश प्राप्त करने का समाधान था!
रे हुलहा

5
ओरेओ में जब ऐप को मार दिया जाता है, तो ऑनमैसेजेज को कॉल नहीं किया जाता है। मेरे पास केवल डेटा के साथ पेलोड है। आपके पास कोई अपडेट है?
समीर मांगरोलिया

2
एक जादू की तरह काम करता है!
ssk

3
इस उत्तर के लिए लव
अहमद अर्सलान

63

इस विधि को संभालता है () मूल्यह्रास किया गया है, इसलिए एक अधिसूचना को नीचे के रूप में किया जा सकता है:

  1. फोरग्राउंड स्टेट: अधिसूचना का क्लिक लंबित इरादे की गतिविधि पर जाएगा, जिसे आप एक सूचना प्रो-व्याकरणिक रूप से बनाते समय प्रदान कर रहे हैं क्योंकि यह आमतौर पर अधिसूचना के डेटा पेलोड के साथ बनाया जाता है।

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


धन्यवाद!!! मैंने इस समस्या पर कुछ दिन खो दिए और इसने मुझे बचा लिया।
इगोर जानकोविओक

वास्तव में सही समाधान!
एडुकैवियर

4
मैं हैंडलेंट लॉजिक (इंट्रेंट इंटेंस) में नोटिफिकेशन डिस्प्ले लॉजिक को हैंडल कर रहा हूं, हालाँकि जब ऐप बैकग्राउंड में होता है, तो 2 नोटिफिकेशन दिखाई देते हैं, एक जिसे मैंने बनाया है और दूसरा डिफॉल्ट रूप से जिसमें नोटिफिकेशन से पूरा मैसेज है।
जॉयसन

5
बहुत बढ़िया, लेकिन मुझे OnMessageReceivedइस मामले में कोई फायदा नहीं दिख रहा है !?
अला अबजारीफा

8
मैं आ रही com.google.firebase: firebase-संदेश: 11.6.2 और handleIntent अंतिम now.Check है stackoverflow.com/questions/47308155/...
रौनक Poriya

31

यहां फायरबेस संदेश के बारे में अधिक स्पष्ट अवधारणाएं हैं। मुझे यह उनकी सपोर्ट टीम से मिला।

फायरबेस के तीन संदेश प्रकार हैं :

अधिसूचना संदेश : अधिसूचना संदेश पृष्ठभूमि या अग्रभूमि पर काम करता है। जब ऐप बैकग्राउंड में होता है, तो नोटिफिकेशन मैसेज सिस्टम ट्रे में डिलीवर हो जाते हैं। यदि अनुप्रयोग अग्रभूमि में है, इसलिए संदेश द्वारा नियंत्रित किया जाता है onMessageReceived()या didReceiveRemoteNotificationकॉलबैक। ये अनिवार्य रूप से प्रदर्शित संदेश के रूप में संदर्भित होते हैं।

डेटा संदेश : एंड्रॉइड प्लेटफॉर्म पर, डेटा संदेश पृष्ठभूमि और अग्रभूमि पर काम कर सकता है। डेटा संदेश onMessageReceived () द्वारा नियंत्रित किया जाएगा। यहां एक प्लेटफ़ॉर्म विशिष्ट नोट होगा: एंड्रॉइड पर, डेटा पेलोड को आपकी गतिविधि लॉन्च करने के लिए उपयोग किए जाने वाले इरादे में पुनर्प्राप्त किया जा सकता है। विस्तृत करने के लिए, यदि आपके पास है, तो आप केवल इसके "click_action":"launch_Activity_1"माध्यम getIntent()से इस आशय को पुनः प्राप्त कर सकते हैं Activity_1

अधिसूचना और डेटा पेलोड दोनों के साथ संदेश : जब पृष्ठभूमि में, एप्लिकेशन अधिसूचना ट्रे में सूचना पेलोड प्राप्त करते हैं, और जब उपयोगकर्ता अधिसूचना पर टैप करता है, तो केवल डेटा पेलोड को संभालता है। अग्रभूमि में होने पर, आपके एप्लिकेशन को उपलब्ध दोनों पेलोड के साथ एक संदेश ऑब्जेक्ट प्राप्त होता है। दूसरे, click_action पैरामीटर अक्सर सूचना पेलोड में उपयोग किया जाता है और डेटा पेलोड में नहीं। यदि डेटा पेलोड के अंदर उपयोग किया जाता है, तो इस पैरामीटर को कस्टम की-वैल्यू पेयर के रूप में माना जाएगा और इसलिए आपको इसके लिए कस्टम लॉजिक लागू करना होगा।

इसके अलावा, मैं आपको डेटा बंडल निकालने के लिए onMessageReceived विधि (डेटा संदेश देखें) का उपयोग करने की सलाह देता हूं। आपके तर्क से, मैंने बंडल ऑब्जेक्ट चेक किया और अपेक्षित डेटा सामग्री नहीं मिली। यहां एक ऐसे ही मामले का संदर्भ दिया गया है जो अधिक स्पष्टता प्रदान कर सकता है।

सर्वर की ओर से, फायरबेस नोटिफिकेशन को प्रारूपित किया जाना चाहिए :

सर्वर साइड को "अधिसूचना" ऑब्जेक्ट भेजना चाहिए । "अधिसूचना" ऑब्जेक्ट के अभाव में मेरे TargetActivityसंदेश का उपयोग नहीं हो रहा था getIntent()

सही संदेश फॉर्मेट दिया गया है:

{
 "data": {
  "body": "here is body",
  "title": "Title"
 },
"notification": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
 "to": "ffEseX6vwcM:APA91bF8m7wOF MY FCM ID 07j1aPUb"
}

यहां फायरबेस संदेश के बारे में अधिक स्पष्ट अवधारणाएं हैं। मुझे यह उनकी सपोर्ट टीम से मिला।

अधिक जानकारी के लिए मेरे इस धागे और इस धागे पर जाएँ


3
उल्लेखनीय है कि "डेटा संदेश" प्राप्त नहीं होगा यदि डिवाइस गहरे डोज मोड में है (एंड्रॉइड 7.0 में पेश किया गया है)। उन लोगों के साथ सावधान रहना!
समीर जे

30

मुझे भी यही समस्या थी। 'सूचना' के बजाय 'डेटा संदेश' का उपयोग करना अधिक आसान है। डेटा संदेश हमेशा कक्षा को लोड करता है।

उस क्लास में आप नोटिफिकेशन के साथ अपना नोटिफिकेशन बना सकते हैं।

उदाहरण:

 @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
    }

    private void sendNotification(String messageTitle,String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT);

        long[] pattern = {500,500,500,500,500};

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setVibrate(pattern)
                .setLights(Color.BLUE,1,1)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

7
धन्यवाद .. मैंने अपना सर्वर कोड बदल दिया और "सूचना" के बजाय "डेटा" का उपयोग किया और अब यह सही काम कर रहा है,
महेश कावथिया

5
@ यह काम कर रहा है केवल अगर एप्लिकेशन पृष्ठभूमि में है तो यह अग्रभूमि में नहीं है। क्या आप मुझे इस घटना को दोनों मामलों में ट्रिगर करने में मदद कर सकते हैं ??
अनंत शाह

@AnantShah Firebase सर्वर पर आपका POST कैसा दिखता है?
कूट जू

3
वास्तव में यहां तीन संभावित मामले हैं। 1) अग्रभूमि में ऐप। 2) बैकग्राउंड में ऐप। 3) ऐप नहीं चल रहा है। जैसा कि आप कहते हैं, एक 'डेटा' संदेश पहले दो मामलों में प्राप्त होगा, लेकिन तीसरे मामले में नहीं , जब ऐप नहीं चल रहा हो। सभी तीन मामलों को पूरा करने के लिए, आपको संदेश में 'अधिसूचना' फ़ील्ड सेट करना होगा। (इसके अलावा एक अच्छा विचार अगर आप iOS के साथ-साथ एंड्रॉइड क्लाइंट का भी समर्थन करना चाहते हैं)
स्टीव मोस्ले

1
यहां तक ​​कि ऐप में भी नहीं चल रहा है, मैं stil को सर्वर से संदेश onmessagereceived पर संदेश मिलता है। मैं आपसे सहमत हूँ कि यदि आप ios का समर्थन करना चाहते हैं तो 'सूचना' का उपयोग करना बेहतर है।
कूट

21

फायरबेस क्लाउड मैसेजिंग डॉक्यूमेंटेशन के अनुसार-यदि एक्टिविटी अग्रभूमि में है, तो ऑनमैसेजेज को कॉल किया जाएगा। यदि गतिविधि पृष्ठभूमि या बंद है, तो एप्लिकेशन लॉन्चर गतिविधि के लिए अधिसूचना केंद्र में अधिसूचना संदेश दिखाया जाता है। अगर आपका ऐप फायरबेस मैसेजिंग के लिए रेस्ट सर्विस एपीआई कॉल करके पृष्ठभूमि में है, तो आप अपनी अनुकूलित गतिविधि को नोटिफिकेशन पर क्लिक कर सकते हैं:

URL- https://fcm.googleapis.com/fcm/send

विधि प्रकार- POST

Header- Content-Type:application/json
Authorization:key=your api key

शारीरिक / पेलोड:

{ "notification": {
    "title": "Your Title",
    "text": "Your Text",
     "click_action": "OPEN_ACTIVITY_1" // should match to your intent filter
  },
    "data": {
    "keyname": "any value " //you can get this data as extras in your activity and this data is optional
    },
  "to" : "to_id(firebase refreshedToken)"
} 

और इसके साथ अपने ऐप में आप नीचे दी गई कोड को अपनी गतिविधि में जोड़ सकते हैं:

<intent-filter>
                <action android:name="OPEN_ACTIVITY_1" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

मैं इरादा कहाँ से बनाऊँगा और क्या यह एक विशिष्ट गतिविधि खोल सकता है? मुझे पता है कि यह OPEN_ACTIVITY_1 मेनिफेस्ट में इरादे को दर्ज करता है, लेकिन मैं वास्तव में इसे कहां कहता हूं?
सायोजनोस


क्या हमें आशय-फ़िल्टर से किसी गतिविधि को कॉल करना चाहिए? या इसे मैन्युअल रूप से शुरू करें onMessageReceived?
कूलमाइंड

14

onMessageReceived (RemoteMessage RemoteMessage) विधि निम्नलिखित मामलों पर आधारित है।

  • अधिसूचना और डेटा ब्लॉक के साथ FCM प्रतिक्रिया :
{
  
"to": "device token list",
  "notification": {
    "body": "Body of Your Notification",
    "title": "Title of Your Notification"
  },
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}
  1. फोरग्राउंड में ऐप:

onMessageReceived (RemoteMessage RemoteMessage) , जिसे सूचना पट्टी में लार्जआईकॉन और बिगपिक्योर दिखाता है। हम अधिसूचना और डेटा ब्लॉक दोनों से सामग्री पढ़ सकते हैं

  1. पृष्ठभूमि में ऐप:

onMessageReceived (RemoteMessage RemoteMessage) को नहीं बुलाया जाता है, सिस्टम ट्रे संदेश को प्राप्त करेगी और सूचना ब्लॉक से बॉडी और शीर्षक पढ़ेगी और सूचना पट्टी में डिफ़ॉल्ट संदेश और शीर्षक दिखाएगा

  • केवल डेटा ब्लॉक के साथ FCM रिस्पांस :

इस मामले में, अधिसूचना ब्लॉक को json से हटा दें

{
  
"to": "device token list",
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}

OnMessageReceived () कॉलिंग के लिए समाधान

  1. फोरग्राउंड में ऐप:

onMessageReceived (RemoteMessage RemoteMessage) , जिसे सूचना पट्टी में लार्जआईकॉन और बिगपिक्योर दिखाता है। हम अधिसूचना और डेटा ब्लॉक दोनों से सामग्री पढ़ सकते हैं

  1. पृष्ठभूमि में ऐप:

onMessageReceived (RemoteMessage RemoteMessage) कहा जाता है, सिस्टम ट्रे को संदेश प्राप्त नहीं होगा क्योंकि अधिसूचना कुंजी प्रतिक्रिया में नहीं है। नोटिफिकेशन बार में लार्जआईकॉन और बिगपिक्योर दिखाता है

कोड

 private void sendNotification(Bitmap bitmap,  String title, String 
    message, PendingIntent resultPendingIntent) {

    NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
    style.bigPicture(bitmap);

    Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

    NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    String NOTIFICATION_CHANNEL_ID = mContext.getString(R.string.default_notification_channel_id);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);

        notificationManager.createNotificationChannel(notificationChannel);
    }
    Bitmap iconLarge = BitmapFactory.decodeResource(mContext.getResources(),
            R.drawable.mdmlogo);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.mdmlogo)
            .setContentTitle(title)
            .setAutoCancel(true)
            .setSound(defaultSound)
            .setContentText(message)
            .setContentIntent(resultPendingIntent)
            .setStyle(style)
            .setLargeIcon(iconLarge)
            .setWhen(System.currentTimeMillis())
            .setPriority(Notification.PRIORITY_MAX)
            .setChannelId(NOTIFICATION_CHANNEL_ID);


    notificationManager.notify(1, notificationBuilder.build());


}

संदर्भ लिंक:

https://firebase.google.com/docs/cloud-messaging/android/receive


पृष्ठभूमि की समस्या से पीड़ित लोगों के लिए सबसे महत्वपूर्ण हिस्सा JSON से "अधिसूचना" संपत्ति को सर्वर द्वारा भेजे जाने से हटाना है। इससे समस्या हल हो जाती है। बहुत बहुत धन्यवाद।
रामी एम। मौसा

13

मुझे वही मुद्दा मिला। यदि एप्लिकेशन अग्रभूमि है - यह मेरी पृष्ठभूमि सेवा को ट्रिगर करता है जहां मैं अधिसूचना प्रकार के आधार पर अपने डेटाबेस को अपडेट कर सकता हूं। लेकिन, ऐप पृष्ठभूमि में जाता है - उपयोगकर्ता को अधिसूचना दिखाने के लिए डिफ़ॉल्ट अधिसूचना सेवा का ध्यान रखा जाएगा।

यहाँ पृष्ठभूमि में ऐप की पहचान करने और अपनी पृष्ठभूमि सेवा को ट्रिगर करने का मेरा समाधान है,

public class FirebaseBackgroundService extends WakefulBroadcastReceiver {

  private static final String TAG = "FirebaseService";

  @Override
  public void onReceive(Context context, Intent intent) {
    Log.d(TAG, "I'm in!!!");

    if (intent.getExtras() != null) {
      for (String key : intent.getExtras().keySet()) {
        Object value = intent.getExtras().get(key);
        Log.e("FirebaseDataReceiver", "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("gcm.notification.body") && value != null) {
          Bundle bundle = new Bundle();
          Intent backgroundIntent = new Intent(context, BackgroundSyncJobService.class);
          bundle.putString("push_message", value + "");
          backgroundIntent.putExtras(bundle);
          context.startService(backgroundIntent);
        }
      }
    }
  }
}

मेनिफेस्ट में .xml

<receiver android:exported="true" android:name=".FirebaseBackgroundService" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </receiver>

नवीनतम Android 8.0 संस्करण में इस समाधान का परीक्षण किया। धन्यवाद


इस FirebaseBackgroundService वर्ग का उपयोग करना चाहते हैं ?? @ नागेंद्र बडिगंती

इस कोड का उपयोग करने के लिए सार्वजनिक वर्ग FirebaseBackgroundService WakefulBroadcastReceiver @Nagendra Badiganti

अपने पैकेज में एक सेवा वर्ग बनाएं और अपने घोषणापत्र में पंजीकृत करें। सुनिश्चित करें कि आपके पास आपकी सूचनाओं के लिए फ़िल्टर है। चूंकि सेवा हर GCM अधिसूचना के लिए ट्रिगर होती है।
नागेंद्र बडिगंती

firebase.google.com/docs/cloud-messaging/android/… मैं इस लिंक का अनुसरण कर रहा हूं, मुझे अधिसूचना प्राप्त करने के लिए इस वर्ग को जोड़ने की आवश्यकता है। सिर्फ फायरबेस संदेश से संदेश भेजना .. यह कहता है पूरा हो गया है लेकिन अधिसूचना प्राप्त नहीं कर रहा है @ नगेंद्र बडिगंती

1
WakefulBroadcastReceiverएपीआई स्तर 26.1.0 के बाद से निकाला गया है।
मिनोरू

12

यदि एप्लिकेशन पृष्ठभूमि मोड या निष्क्रिय (मार डाला) में है, और आप अधिसूचना पर क्लिक करते हैं , तो आपको लॉन्चस्क्रीन में पेलोड के लिए जांच करनी चाहिए (मेरे मामले में लॉन्च स्क्रीन MainActivity.java है)।

तो में MainActivity.java पर onCreate के लिए चेक अतिरिक्त :

    if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Log.d("MainActivity: ", "Key: " + key + " Value: " + value);
        }
    }

मैं सूचना शीर्षक, निकाय और डेटा कैसे प्राप्त कर सकता हूं?
Md.Tarikul इस्लाम

1
धन्यवाद, यह उत्तर है। @ Md.Tarikul इस्लाम onMessageReceived () का उपयोग इस प्रश्न में किया गया है।
felixwcf

7

मेरे लिए कार्य की handleIntentविधि को ओवरराइड करें FirebaseMessageService

यहाँ C # (Xamarin) में कोड

public override void HandleIntent(Intent intent)
{
    try
    {
        if (intent.Extras != null)
        {
            var builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            foreach (string key in intent.Extras.KeySet())
            {
                builder.AddData(key, intent.Extras.Get(key).ToString());
            }

            this.OnMessageReceived(builder.Build());
        }
        else
        {
            base.HandleIntent(intent);
        }
    }
    catch (Exception)
    {
        base.HandleIntent(intent);
    }
}

और जावा में कोड है

public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }

            onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}

handleIntent () अंतिम है
Ettore

@Ettore मैं कैसे संभाल कर सकते हैंइन्वेंट फ़ंक्शन?
Hiroto

जब आप फायरबेस से संदेश प्राप्त करते हैं, तो विधि को कहा जाता है, लेकिन आप अंतिम रूप से घोषित किए जाने के कारण ओवरराइड नहीं कर सकते। (फायरबेस ११.६.०)
१ore

5

डिफ़ॉल्ट रूप से आपके ऐप में लॉन्चर एक्टिविटी लॉन्च हो जाएगी जब आपका ऐप बैकग्राउंड में होगा और आप नोटिफिकेशन पर क्लिक करेंगे, अगर आपके पास अपने नोटिफिकेशन के साथ कोई डेटा पार्ट है तो आप इसे उसी एक्टिविटी में निम्न प्रकार से हैंडल कर सकते हैं,

if(getIntent().getExtras()! = null){
  //do your stuff
}else{
  //do that you normally do
}

यदि मैं मुख्यता से नेविगेट करता हूं, तो विशेष गतिविधि पर वापस कैसे नेविगेट करेगा?
Mac_Play

।? @Uzair getIntent () getExtras () हमेशा अशक्त हो रही है, तो आप किसी अन्य समाधान है जब एप्लिकेशन bacground जा रहा है onMessageReceived विधि कॉल न करें
user2025187

3

यदि एप्लिकेशन बैकग्राउंड हैंडलिंग डिफॉल्ट नोटिफिकेशन द्वारा फायर-बेस में है, लेकिन यदि हम अपने कस्टम नोटिफिकेशन से चाहते हैं कि हमें अपना सर्वर साइड बदलना है, जो हमारे कस्टम डेटा (डेटा पेलोड) को भेजने के लिए जिम्मेदार है

अपने सर्वर अनुरोध से पूरी तरह से अधिसूचना पेलोड निकालें। केवल डेटा भेजें और इसे onMessageReceived () में संभाल लें अन्यथा जब ऐप बैकग्राउंड में होगा या मार दिया जाएगा तो आपका onMessageReceived ट्रिगर नहीं होगा।

अब, आपका सर्वर साइड कोड प्रारूप जैसा दिखता है,

{
  "collapse_key": "CHAT_MESSAGE_CONTACT",
  "data": {
    "loc_key": "CHAT_MESSAGE_CONTACT",
    "loc_args": ["John Doe", "Contact Exchange"],
    "text": "John Doe shared a contact in the group Contact Exchange",
    "custom": {
      "chat_id": 241233,
      "msg_id": 123
    },
    "badge": 1,
    "sound": "sound1.mp3",
    "mute": true
  }
}

नोट : इस लाइन को उपरोक्त कोड
"टेक्स्ट" में देखें: "जॉन डो ने डेटा पेलोड में ग्रुप कॉन्टैक्ट एक्सचेंज में एक कॉन्टैक्ट साझा किया है। आपको संदेश वर्णन के लिए" बॉडी "या" मैसेज "पैरामीटर के बजाय" टेक्स्ट "पैरामीटर का उपयोग करना चाहिए या आप जो भी हो पाठ का उपयोग करना चाहते हैं।

onMessageReceived ()

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.e(TAG, "From: " + remoteMessage.getData().toString());

        if (remoteMessage == null)
            return;

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
           /* Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());*/
            Log.e(TAG, "Data Payload: " + remoteMessage);

            try {

                Map<String, String> params = remoteMessage.getData();
                JSONObject json = new JSONObject(params);
                Log.e("JSON_OBJECT", json.toString());


                Log.e(TAG, "onMessageReceived: " + json.toString());

                handleDataMessage(json);
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }

2

बस इसे अपने MainActivity की ऑनक्रीट विधि में कहें:

if (getIntent().getExtras() != null) {
           // Call your NotificationActivity here..
            Intent intent = new Intent(MainActivity.this, NotificationActivity.class);
            startActivity(intent);
        }

यदि मैं मुख्यता से नेविगेट करता हूं, तो विशेष गतिविधि पर वापस कैसे नेविगेट करेगा?
Mac_Play

2

t3h exi से समाधान के अनुसार मैं यहाँ स्वच्छ कोड पोस्ट करना चाहूंगा। अगर एप्लिकेशन बैकग्राउंड मोड में है तो बस इसे MyFirebaseMessagingService में डालें और सब कुछ ठीक चले। आपको कम से कम com.google.firebase: फायरबेस-मैसेजिंग: 10.2.1 संकलित करने की आवश्यकता है

 @Override
public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }



           onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}

मैं आपके समाधान को लागू करने की कोशिश कर रहा हूं, लेकिन मेरे एसडीके संस्करण (एसडीके 27) में हैंडिलेंट () विधि अंतिम है, इसलिए मैं इसे अपनी सेवा में ओवरराइड नहीं कर सकता ...
मटका 31

हाँ, लेकिन मेरी गलती या कोई कारण नहीं देने के लिए -1 !!! बहुत घमंडी है। यह फायरबेस 11.4.2 तक काम करता है तब Google ने इसे बदल दिया (इस विधि को अंतिम रूप दिया)। तो अब आपको अपने खुद के समाधान को अधिसूचना के साथ प्रोग्राम करना होगा।
फ्रैंक

मैंने -1 नहीं बल्कि +1 दिया!
मटदेव

तुम मेरी नौकरी बचाओ: P
amitabha2715

2

इसे इस्तेमाल करे:

public void handleIntent(Intent intent) {
    try {
        if (intent.getExtras() != null) {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");
            for (String key : intent.getExtras().keySet()) {
            builder.addData(key, intent.getExtras().get(key).toString());
        }
            onMessageReceived(builder.build());
        } else {
            super.handleIntent(intent);
        }
    } catch (Exception e) {
        super.handleIntent(intent);
    }
}

handleIntent का उपयोग अब फायरबेस में नहीं किया जाता है: 11.8.0 और ऊपरी।
शिहाब उद्दीन

1

मेरे पास यह मुद्दा था (एप्लिकेशन पृष्ठभूमि या बंद होने पर अधिसूचना पर क्लिक करना नहीं चाहता है), और समस्या click_actionअधिसूचना निकाय में एक अमान्य थी, इसे हटाने या इसे किसी मान्य चीज़ में बदलने का प्रयास करें।


1

जो बिंदु हाइलाइटिंग के योग्य है, वह यह है कि आपको डेटा संदेश - डेटा कुंजी का उपयोग करना है - onMessageReceived हैंडलर प्राप्त करने के लिए जब ऐप पृष्ठभूमि में हो। आपके पास आपके पेलोड में कोई अन्य सूचना संदेश कुंजी नहीं होनी चाहिए, अन्यथा ऐप पृष्ठभूमि में होने पर हैंडलर ट्रिगर नहीं होगा।

यह उल्लेख किया गया है (लेकिन FCM प्रलेखन में इतना जोर नहीं दिया गया है):

https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

अपने ऐप सर्वर और FCM सर्वर API का उपयोग करें: डेटा कुंजी केवल सेट करें । संकुचित या गैर-बंधनेवाला हो सकता है।


1

मैं जिस बैकएंड के साथ काम कर रहा हूं वह अधिसूचना संदेशों का उपयोग कर रहा है न कि डेटा संदेशों का। इसलिए सभी उत्तरों को पढ़ने के बाद मैंने एक्सट्रैस को उस इरादे के बंडल से पुनर्प्राप्त करने का प्रयास किया जो लॉन्च की गई गतिविधि के लिए आता है। लेकिन इससे कोई फर्क नहीं पड़ता कि मैंने किन चाबियों को प्राप्त करने की कोशिश की getIntent().getExtras();, मूल्य हमेशा शून्य था।

हालाँकि, मुझे अंततः अधिसूचना संदेशों का उपयोग करके डेटा भेजने और इसे इरादे से पुनर्प्राप्त करने का एक तरीका मिला ।

यहां कुंजी डेटा पेलोड को अधिसूचना संदेश में जोड़ना है ।

उदाहरण:

{
    "data": {
        "message": "message_body",
        "title": "message_title"
    },
    "notification": {
        "body": "test body",
        "title": "test title"
    },
    "to": "E4An.."
}

ऐसा करने के बाद, आप अपनी जानकारी इस तरह से प्राप्त कर पाएंगे:

intent.getExtras().getString("title") होगा message_title

और intent.getExtras().getString("message") होगाmessage_body

संदर्भ


1

यदि आपकी समस्या बिग इमेज दिखाने से संबंधित है यानी यदि आप फायरबेस कंसोल से इमेज के साथ पुश नोटिफिकेशन भेज रहे हैं और यह इमेज तभी प्रदर्शित करता है, जब ऐप अग्रभूमि में हो। इस समस्या का हल केवल डेटा फ़ील्ड के साथ एक पुश संदेश भेजना है। कुछ इस तरह:

{ "data": { "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg", "message": "Firebase Push Message Using API" "AnotherActivity": "True" }, "to" : "device id Or Device token" }

आपने "अन्यता" से पहले अल्पविराम खो दिया। मेरा Android कंपन करता है लेकिन वास्तव में कुछ भी नहीं दिखाया गया है (कोई पाठ नहीं, कोई छवि नहीं, कोई धक्का नहीं)।
जेकबाई

1

जब संदेश प्राप्त होता है और आपका ऐप पृष्ठभूमि में होता है तो अधिसूचना को मुख्य गतिविधि के एक्स्ट्रा इरादे को भेज दिया जाता है।

आप मुख्य गतिविधि के oncreate () या onresume () फ़ंक्शन में अतिरिक्त मान की जांच कर सकते हैं।

आप डेटा, तालिका आदि जैसे क्षेत्रों के लिए जांच कर सकते हैं (अधिसूचना में निर्दिष्ट)

उदाहरण के लिए मैंने कुंजी के रूप में डेटा का उपयोग करके भेजा है

public void onResume(){
    super.onResume();
    if (getIntent().getStringExtra("data")!=null){
            fromnotification=true;
            Intent i = new Intent(MainActivity.this, Activity2.class);
            i.putExtra("notification","notification");
            startActivity(i);
        }

}

0

मैं एक ही मुद्दा रहा था और इस पर कुछ और खुदाई किया था। एप्लिकेशन पृष्ठभूमि में, एक सूचना संदेश सिस्टम ट्रे के लिए भेजा है, लेकिन एक डेटा संदेश को भेजा जाता है onMessageReceived()
देखें https://firebase.google.com/docs/cloud-messaging/downstream#monitor-token-generation_3
और https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java

यह सुनिश्चित करने के लिए कि आप जो संदेश भेज रहे हैं, डॉक्स कहते हैं, " अपने ऐप सर्वर और FCM सर्वर API का उपयोग करें: डेटा कुंजी केवल सेट करें। या तो समाप्‍त या गैर-बंधनीय हो सकती है। " https://firebase.google.com/
देखें डॉक्स / बादल-संदेश / अवधारणा-विकल्पों # notifications_and_data_messages


0

दो प्रकार के संदेश हैं: सूचना संदेश और डेटा संदेश। यदि आप केवल डेटा संदेश भेजते हैं, जो आपके संदेश स्ट्रिंग में सूचना ऑब्जेक्ट के बिना है। जब आपका ऐप बैकग्राउंड में होगा तो इसे इन्वाइट किया जाएगा।


0

@ महेश कावठिया के जवाब की जाँच करें। मेरे केस के लिए, सर्वर कोड में केवल यह है:

{
"notification": {
  "body": "here is body",
  "title": "Title",
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

आपको इसे बदलने की आवश्यकता है:

{
 "data": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
"notification": {
  "body": "here is body",
  "title": "Title"
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

फिर, बैकग्राउंड में केस ऐप में, डिफॉल्ट एक्टिविटी इंट्रेस्ट एक्स्ट्रा को "डेटा" मिलेगा

सौभाग्य!


-1

बस FirebaseMessagingService की OnCreate विधि को ओवरराइड करें। यह तब कहा जाता है जब आपका ऐप पृष्ठभूमि में हो:

public override void OnCreate()
{
    // your code
    base.OnCreate();
}

यदि आप स्पष्टीकरण जोड़ सकते हैं, और कुछ दस्तावेज़ीकरण के लिए यह उत्तर अधिक उपयोगी हो सकता है। क्या आप हमें बता सकते हैं कि यह कैसे मदद करने वाला है?
किलोकाहन

@kilokahn क्या आप मुझे समझा सकते हैं कि आप क्या नहीं समझते हैं? संकेतित पद्धति को उस कोड में डाला जाना चाहिए जो प्रश्न का हिस्सा है और प्रश्न का पूर्ण उत्तर देता है। कोड Xamarin के लिए है, लेकिन आप बस जावा में बदल सकते हैं।
Renzo Ciot

AFAIK आधिकारिक दस्तावेज ( firebase । इसके अलावा, आपके उत्तर से, यह स्पष्ट नहीं है कि ओवरराइडिंग ऑनक्रिएट किस तरह से ऑन-मेसेजेज की समस्या को हल करता है। जब अधिसूचना पर क्लिक किया जाता है तो कॉल नहीं किया जा रहा है - इसलिए अधिक जानकारी के लिए अनुरोध।
किलोकहं

प्रलेखन ऑनक्रीट विधि के ओवरराइड का उल्लेख नहीं करता है, लेकिन यह काम करता है क्योंकि मैं इसे उत्पादन में उपयोग कर रहा हूं। वह कोड जिसे आप ऑनमैसेजेज विधि में सम्मिलित करना चाहते हैं और जो स्पष्ट रूप से कुछ पृष्ठभूमि कार्य करने के लिए कार्य करता है, ऑनक्रैट पर किया जा सकता है।
रेनजो सियोट

उस मामले में, इस तथ्य पर विस्तृत रूप से कि यह आपके लिए किसी भी तरह काम करता है, समाधान को सूचीबद्ध करने की तुलना में अधिक उपयोगी साबित हो सकता है। इसके अलावा, अनियंत्रित व्यवहार अपडेट के साथ मनमाने ढंग से काम करना बंद करने की संभावना है, और उनका उपयोग करने वाले किसी व्यक्ति को अपने कोड को फिर से तैयार करने के लिए तैयार रहना होगा। इस डिस्क्लेमर को डालने की जरूरत है।
किलोकान

-1

कर रहे हैं 2 प्रकार के Firebase धक्का अधिसूचना:

1- अधिसूचना संदेश (प्रदर्शन संदेश) -> - 1.1 यदि आप इस संस्करण को चुनते हैं, तो ओएस इसे स्वयं अधिसूचना बना देगा यदि ऐप पृष्ठभूमि में है और डेटा को पास करेगा intent। फिर इस डेटा को संभालने के लिए क्लाइंट पर निर्भर है।

- 1.2 अनुप्रयोग में है, तो अग्रभूमि तो अधिसूचना यह के माध्यम से प्राप्त किया जाएगा callback-functionमें FirebaseMessagingServiceहै और यह इसे संभाल करने के लिए ग्राहक पर निर्भर है।

2- डेटा संदेश (4k डेटा तक) -> इन संदेशों का उपयोग क्लाइंट को केवल डेटा भेजने के लिए किया जाता है (चुपचाप) और यह कॉलबैक-फंक्शन के माध्यम से दोनों मामलों की पृष्ठभूमि / अग्रभूमि के लिए इसे संभालने के लिए क्लाइंट पर निर्भर है। FirebaseMessagingService

यह आधिकारिक डॉक्स के अनुसार है: https://firebase.google.com/docs/cloud-messaging/concept-options

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.