Firebase में बैकग्राउंड में ऐप होने पर नोटिफिकेशन को कैसे हैंडल करें


426

यहाँ मेरी अभिव्यक्ति है

    <service android:name=".fcm.PshycoFirebaseMessagingServices">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <service android:name=".fcm.PshycoFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

जब ऐप बैकग्राउंड में होता है और नोटिफिकेशन आता है तो डिफॉल्ट नोटिफिकेशन आता है और मेरा कोड नहीं चलता है onMessageReceived

यहाँ मेरा onMessageReceivedकोड है। अगर मेरा ऐप बैकग्राउंड में नहीं चल रहा है, तो बैकग्राउंड में ऐप होने पर यह इनवाइट करता है। जब ऐप बैकग्राउंड में भी हो तो इस कोड को कैसे चलाएं?

// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // If the application is in the foreground handle both data and notification messages here.
    // 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.
    data = remoteMessage.getData();
    String title = remoteMessage.getNotification().getTitle();
    String message = remoteMessage.getNotification().getBody();
    String imageUrl = (String) data.get("image");
    String action = (String) data.get("action");
    Log.i(TAG, "onMessageReceived: title : "+title);
    Log.i(TAG, "onMessageReceived: message : "+message);
    Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
    Log.i(TAG, "onMessageReceived: action : "+action);

    if (imageUrl == null) {
        sendNotification(title,message,action);
    } else {
        new BigPictureNotification(this,title,message,imageUrl,action);
    }
}
// [END receive_message]

1
यह दूसरी टिप्पणी पंक्ति कहती है कि ऑनमैसेजReceived () के ओवरराइड नमूने में लिखा गया है Not getting messages here? See why this may be: goo.gl/39bRNJ । नीचे दिए गए उत्तरों की तरह इसका समाधान
मैसेजिंग में

अपने मारे गए ऐप को जगाने के लिए, अपने एप्लिकेशन में अपने नोटिफिकेशन सर्विस क्लास हैंडलबार FirebaseMessagingService.onMessageReceived () को कॉल करने के लिए आपको हमेशा डेटा ऑब्जेक्ट के साथ सूचना भेजनी चाहिए। इसे फायरबेस कंसोल से नहीं भेजने की कोशिश करें, लेकिन इसे कहीं और से पोस्ट करने के लिए (जैसे ऑनलाइन परीक्षण पोस्ट सेवा)।
ज़ोन

1
इस समाधान ने मेरे लिए काम किया stackoverflow.com/a/44150822/6632278 आशा है कि मदद करता है। सौभाग्य
टोनी बाराजास

क्या ".fcm।" PshycoFirebaseMessagingServices आपके प्रकटन में है? मुझे कक्षा नहीं मिली की त्रुटि हो रही है .. और कहीं भी नहीं मिला कि यह पैरामीटर का पहला भाग क्या है।
22डर रोचा बीज़र्रा

जवाबों:


660

1. ऐसा क्यों हो रहा है?

FCM (फायरबेस क्लाउड मेसेजिंग) में दो प्रकार के संदेश हैं:

  1. संदेश प्रदर्शित करें : ये संदेश onMessageReceived()केवल कॉलबैक को ट्रिगर करते हैं जब आपका ऐप अग्रभूमि में होता है
  2. डेटा संदेश : आपके संदेश अग्रभूमि / पृष्ठभूमि / मारे जाने पर भी थिसिस संदेश onMessageReceived()कॉलबैक को ट्रिगर करता है

नोट: फायरबेस टीम ने data-messagesआपके उपकरणों को भेजने के लिए यूआई विकसित नहीं किया है, फिर भी। आपको इस प्रकार भेजने के लिए अपने सर्वर का उपयोग करना चाहिए!



2. कैसे?

इसे प्राप्त करने के लिए, आपको POSTनिम्नलिखित URL पर एक अनुरोध करना होगा:

POST https://fcm.googleapis.com/fcm/send

हेडर

  • कुंजी: Content-Type , मान: application/json
  • कुंजी: Authorization , मान: key=<your-server-key>

विषयों का उपयोग करने वाला शरीर

{
    "to": "/topics/my_topic",
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     }
}

या यदि आप इसे विशिष्ट उपकरणों पर भेजना चाहते हैं

{
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     },
    "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}


नोट: सुनिश्चित करें कि आप JSON कुंजी नहीं जोड़ रहे हैं notification
नोट: अपना सर्वर कुंजी प्राप्त करने के लिए, आप इसे फायरबेस कंसोल में पा सकते हैं:Your project -> settings -> Project settings -> Cloud messaging -> Server Key

3. पुश नोटिफिकेशन मैसेज को कैसे हैंडल करें?

यह है कि आप प्राप्त संदेश को कैसे संभालते हैं:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String myCustomKey = data.get("my_custom_key");

     // Manage data
}

4
आप इन चरणों में एक ही नोटिफिकेशन में "डेटा" और "नोटिफिकेशन" कुंजियाँ भेज सकते हैं, इन चरणों के बाद stackoverflow.com/a/42279260/2734021 :)
डैनियल एस।

15
Firebase team have not developed a UI to send data-messages to your devices, yet.क्या यह पिछले एक साल में बदल गया है?
हांक्रेकर्स

2
@Antonio ओरिओ में जब ऐप को मार दिया गया, onMessageReceived को नहीं बुलाया जा रहा है। मेरे पास केवल डेटा के साथ पेलोड है। आपके पास कोई अपडेट है?
समीर मांगरोलिया

63
जब एप्लिकेशन पृष्ठभूमि में onMessageReceivedहोता है तो कॉल नहीं किया जाता है और यह FCM में एक गंभीर मुद्दा है !!! कृपया अपना उत्तर भी अपडेट करें।
मुहम्मद बाबर

2
खैर, मेरे लिए, ऐसा लगता है कि यह कुछ Android उपकरणों पर होता है। यह सोचते हुए कि यह एक वास्तविक मुद्दा था, लेकिन तब कुछ भी नहीं निकला। इसलिए मेरी सलाह है कि विभिन्न उपकरणों पर इसका परीक्षण करें। मैंने इसे वीएम पर भी परीक्षण किया और ऐप के मारे जाने पर भी मुझे इसकी सूचना मिली। मैं यह किसी के समय को बचाने के लिए कह रहा हूं।
तारेक-देव

158

निम्नलिखित मामलों में अपने onMessageReceived () को कॉल करने के लिए फायरबेस लाइब्रेरी बनाएं

  1. अग्रभूमि में ऐप
  2. पृष्ठभूमि में अनुप्रयोग
  3. ऐप को मार दिया गया है

आपको अपने अनुरोध को JSON की 'नोटिफिकेशन' को Firebase API में नहीं डालना चाहिए, बल्कि 'डेटा' का उपयोग करना चाहिए, नीचे देखें।

जब आपका ऐप बैकग्राउंड में है या मार दिया गया है, तो निम्न संदेश आपके onMessageReceived () को कॉल नहीं करेगा और आप उसकी सूचना को अनुकूलित नहीं कर सकते।

{
   "to": "/topics/journal",
   "notification": {
   "title" : "title",
   "text": "data!",
   "icon": "ic_notification"
    }
}

लेकिन इसके बजाय यह काम करेगा

{
  "to": "/topics/dev_journal",
   "data": {
       "text":"text",
       "title":"",
       "line1":"Journal",
       "line2":"刊物"
   }
} 

मूल रूप से, संदेश आपके डेटा ऑब्जेक्ट के साथ मैप के रूप में तर्क RemoteMessage में भेजा जाता है, तो आप अधिसूचना को प्रबंधित कर सकते हैं।

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();

     //you can get your text message here.
     String text= data.get("text");


     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        // optional, this is to make beautiful icon
             .setLargeIcon(BitmapFactory.decodeResource(
                                    getResources(), R.mipmap.ic_launcher))  
        .setSmallIcon(smallIcon)  //mandatory
      .......
    /*You can read more on notification here:
    https://developer.android.com/training/notify-user/build-notification.html
    https://www.youtube.com/watch?v=-iog_fmm6mE
    */
}

1
क्या फायरबेस कंसोल से इसे हासिल करना संभव है?
कोडर

@ कोडर, दुर्भाग्यवश फायरबेस कंसोल इसका समर्थन नहीं करता है, आपको फायरबस जैसे कर्ल या पोस्टमैन (क्रोम प्लगइन) को पोस्ट मैसेज रिक्वेस्ट भेजने के लिए टूल का उपयोग करना होता है, फायरबेस मैसेजिंग एपी कृपया यहां डॉक्यूमेंट देखें - फायरबेस
Teerakiat Chitawattanarat

1
यह वही है जो मैं एक दिन से अधिक खोज रहा था ..... बहुत बहुत धन्यवाद यह पूरी तरह से काम किया। और यह बेहतर होगा यदि आप यह बताएं कि कैसे डेटा में प्रमुख vale जोड़े को उन मूल्यों के साथ एक गतिविधि शुरू करने के लिए onMessageReceived () में संभाला जा सकता है।
बोओपथी टी

25
एप्लिकेशन बैकग्राउंड में होने पर आपकी विधि ठीक काम करती है, हालांकि जब ऐप मारा जाता है तो मुझे डेटा प्राप्त नहीं हो रहा है
Sanzhar

8
सांझर की भी यही समस्या है। यदि ऐप मारा जाता है तो मुझे कोई संदेश नहीं मिलता है।
जियाकोमो एम

104

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

इन चरणों का पालन करें और जब आपका ऐप बैकग्राउंड में होगा तब आप अपने नोटिफिकेशन को प्रोसेस कर पाएंगे।

1. इस तरह एक इरादे-फिल्टर जोड़ें:

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

एक गतिविधि जिसे आप सूचना डेटा को संसाधित करना चाहते हैं।

  1. अगले प्रारूप के साथ सूचनाएं भेजें:

    { 
     "notification" : {
            "click_action" : ".MainActivity", 
            "body" : "new Symulti update !", 
            "title" : "new Symulti update !", 
            "icon" : "ic_notif_symulti" }, 
     "data": { ... },
     "to" : "c9Vaa3ReGdk:APA91bH-AuXgg3lDN2WMcBrNhJZoFtYF9" }

यहां कुंजी जोड़ दी गई है

"click_action" : ".MainActivity"

जहाँ .MainActivity आप चरण 1 में जोड़े गए आशय-फ़िल्टर के साथ गतिविधि है।

  1. ".MainActivity" के नोटिफिकेशन में नोटिफिकेशन से "डेटा" जानकारी प्राप्त करें:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //get notification data info
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
           //bundle must contain all info sent in "data" field of the notification
        }
    }

और आपको बस इतना करना चाहिए। मुझे आशा है कि यह किसी की मदद करता है :)


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

@airowe वे दिखाने के लिए अधिसूचना के लिए आवश्यक नहीं हैं
AlwaysConfused

मेरे पास डेटा और सूचना ब्लॉक दोनों हैं लेकिन मैं गतिविधि में डेटा प्राप्त करने में सक्षम नहीं हूं?
अश्वनी

3
मुझे अभी समझ नहीं आया कि यह स्वीकृत उत्तर कैसे नहीं है। Click_action के बिना, यह सिर्फ काम नहीं करेगा। मेरा दिन बचा
अरुण शंकर

4
आपके समर्थन के लिए धन्यवाद @ अरुणशंकर। स्वीकृत उत्तर का जवाब मेरा और उसके अच्छे जवाब के 7 महीने पहले दिया गया था। मुझे समझ नहीं आ रहा है कि कोई भी क्लिक_एक्शन के बारे में बात क्यों नहीं करता है और इसीलिए मैंने अपना उत्तर जोड़ा है। मुझे बहुत खुशी है कि यह बहुत से लोगों के लिए बहुत उपयोगी है और दिन के अंत में यही मायने रखता है :)
डैनियल एस।

42

Firebase का उपयोग करके डाउनस्ट्रीम में फायरबैस प्रलेखन के अनुसार , पेलोड 2 प्रकार का होता है:

  1. डेटा

    यह पैरामीटर संदेश के पेलोड के कस्टम की-वैल्यू पेयर को निर्दिष्ट करता है। डेटा संदेशों को संसाधित करने के लिए क्लाइंट ऐप जिम्मेदार है। डेटा संदेशों में केवल कस्टम कुंजी-मूल्य जोड़े होते हैं।

  2. अधिसूचना

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

जब आप अग्रभूमि में होते हैं तो आप onMessageReceived () का उपयोग करके FCM के अंदर डेटा प्राप्त कर सकते हैं , आप अपना डेटा डेटा पेलोड से प्राप्त कर सकते हैं ।

data = remoteMessage.getData();
String customData = (String) data.get("customData");

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

{
  "notification": {
        "title" : "title",
        "body"  : "body text",
        "icon"  : "ic_notification",
        "click_action" : "OPEN_ACTIVITY_1"
       }
}

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

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

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

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

Bundle b = getIntent().getExtras();
String someData = b.getString("someData");

मैं अपने एंड्रॉइड ऐप के लिए FCM का उपयोग कर रहा हूं और पेलोड दोनों का उपयोग कर रहा हूं। यहाँ उदाहरण JSON का उपयोग कर रहा हूँ:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification",
    "click_action" : "OPEN_ACTIVITY_1"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

"एप्लिकेशन टैग के अंदर, अपने इरादे को प्रकट करें।" आप एप्लिकेशन टैग के अंदर आशय-फ़िल्टर नहीं लगा सकते।
Kyrylo Zapylaiev

आपका JSON नहीं दिखाता है कि click_action कुंजी कहां जाती है।
जोश

यह सही उत्तर नहीं है? क्लिक एक्शन n क्या होता है? कुछ को वोट डाउन करना चाहिए या इसे साफ करना चाहिए
राणा

1
@KyryloZapylaiev मैं सही उत्तर देता हूं और उत्तर देता हूं: "अपनी गतिविधि टैग के अंदर अपने प्रकट होने पर उस इरादे को फ़िल्टर करें"।
डिका

1
@ जोश को अद्यतन और स्वरूपित किया गया। आप इसे फिर से देख सकते हैं
Dika

32

डॉक्स के अनुसार

पृष्ठभूमि वाले ऐप में संदेशों को संभालें

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

इसमें वे संदेश शामिल हैं जिनमें अधिसूचना और डेटा पेलोड दोनों शामिल हैं। इन मामलों में, अधिसूचना डिवाइस के सिस्टम ट्रे में वितरित की जाती है, और डेटा पेलोड को आपके लॉन्चर गतिविधि के इरादे के अतिरिक्त में दिया जाता है।

यदि आप अपना ऐप खोलना चाहते हैं और एक विशिष्ट कार्रवाई करना चाहते हैं, तो नोटिफिकेशन पेलोड में क्लिक_एक्शन सेट करें और इसे आप जिस गतिविधि में लॉन्च करना चाहते हैं, उसमें एक इरादे फ़िल्टर पर मैप करें। उदाहरण के लिए, OPEN_ACTIVITY_1 पर क्लिक_ऐक्शन सेट करें ताकि निम्नलिखित की तरह एक आशय फ़िल्टर को ट्रिगर किया जा सके:

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

संपादित करें:

इस धागे के आधार पर :

आप Firebase कंसोल का उपयोग करके click_action पेलोड सेट नहीं कर सकते। आप कर्ल कमांड या कस्टम http सर्वर के साथ परीक्षण का प्रयास कर सकते हैं

curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>" 
     --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  
     -d "{\"to\":\"/topics/news\",\"notification\": 
         {\"title\": \"Click Action Message\",\"text\": \"Sample message\",
            \"click_action\":\"OPEN_ACTIVITY_1\"}}"

1
तुम सही हो। मैंने डॉक्स पढ़ा है। लेकिन im उलझन में है कि यह मेरे प्रकट में कहां रखा जाए? मैं onMessageReceived पर कोड चलाने के लिए है कि जावा फ़ाइल पर तो इसके लिए मुझे क्या करना चाहिए सर?
पार्थ पटेल

जब आप पृष्ठभूमि पर होते हैं तो आप ऐप को स्वचालित रूप से onMessageReveiced नहीं कर सकते। इसके बजाय आपको प्राप्त इरादे को संभालने और हैंडलर को कॉल करने की आवश्यकता है। या शायद यह अलग वर्ग / विधि को लागू करने के लिए सबसे अच्छा है जो ऑनमैसेजेज और आपके इरादे को संभालने वाले दोनों द्वारा बुलाया जाता है। मैंने मुख्य गतिविधि के चालू करने के लिए हैंडलर को जोड़ा और यह मेरे लिए ठीक काम करता है।
दीदू

@Parath पटेल के सवालों का जवाब देने में बहुत देर हो गई लेकिन शायद यह किसी और की समस्याओं में मदद करेगा, मेरे जवाब पर एक नज़र डालें यहां stackoverflow.com/a/42279260/2734021
डैनियल एस।

इसके लिए यह कार्रवाई कहां करनी थी? मेरी गतिविधि या Firebasemessage सेवा के लिए?
महदी

** कई अधिसूचना पर पुनर्निर्देशन काम नहीं कर रहा है? उदाहरण: अगर मेरे पास "क्लिक_एक्शन" का उपयोग करके पृष्ठभूमि पर fcm से तीन अधिसूचना है, तो पहली अधिसूचना सफलतापूर्वक पुनर्निर्देशित हो गई और फिर 2 सूचना पर क्लिक करें गतिविधि पुनर्निर्देशन काम नहीं कर रहा है
prasanthMurugan

24

जुलाई 2019 तक कार्य करना

Android compileSdkVersion 28, buildToolsVersion 28.0.3 और फायरबेस-मैसेजिंग: 19.0.1

अन्य सभी स्टैकऑवरफ्लो प्रश्नों और उत्तरों के माध्यम से कई घंटों के शोध के बाद, और असंख्य आउटडेटेड समाधानों को आज़माने के बाद, यह समाधान इन 3 परिदृश्यों में सूचनाएँ दिखाने में कामयाब रहा:

- ऐप अग्रभूमि में है:
सूचना MyMirebaseMessagingService वर्ग पर onMessageReceived विधि द्वारा प्राप्त की गई है

- ऐप को मार दिया गया है (यह पृष्ठभूमि में नहीं चल रहा है): एफसीएम द्वारा अधिसूचना स्वचालित रूप से अधिसूचना ट्रे को भेजी जाती है। जब उपयोगकर्ता अधिसूचना को छूता है, तो ऐप उस गतिविधि को कॉल करके लॉन्च किया जाता है जिसमें प्रकट में android.intent.category.LAUNCHER है। आप getIntent ()। GetExtras () onCreate () पद्धति का उपयोग करके अधिसूचना का डेटा भाग प्राप्त कर सकते हैं।

- ऐप पृष्ठभूमि में है: अधिसूचना एफसीएम द्वारा स्वचालित रूप से अधिसूचना ट्रे को भेजी जाती है। जब उपयोगकर्ता अधिसूचना को छूता है, तो ऐप को गतिविधि में लॉन्च करके अग्रभूमि में लाया जाता है जिसमें प्रकट में android.intent.category.LAUNCHER है। जैसा कि मेरे ऐप ने लॉन्च किया है, उस गतिविधि में "एकल" को लॉन्च किया है, ऑनक्रिएट () विधि को नहीं कहा जाता है क्योंकि उसी वर्ग की एक गतिविधि पहले से ही बनाई गई है, इसके बजाय उस कक्षा का ऑन-एंटेंट () विधि कहा जाता है और आपको डेटा का हिस्सा मिलता है अभिप्रेरणा .getExtras () का उपयोग करके वहां सूचना।

चरण: 1- यदि आप अपने ऐप की मुख्य गतिविधि को इस तरह परिभाषित करते हैं:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:screenOrientation="portrait"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name=".MainActivity" />
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

2- अपने मेनऐक्टिविटी.क्लास की ऑनक्रिएट () विधि में इन पंक्तियों को जोड़ें

Intent i = getIntent();
Bundle extras = i.getExtras();
if (extras != null) {
    for (String key : extras.keySet()) {
        Object value = extras.get(key);
        Log.d(Application.APPTAG, "Extras received at onCreate:  Key: " + key + " Value: " + value);
    }
    String title = extras.getString("title");
    String message = extras.getString("body");
    if (message!=null && message.length()>0) {
        getIntent().removeExtra("body");
        showNotificationInADialog(title, message);
    }
}

और एक ही MainActivity.class करने के लिए ये तरीके:

@Override
public void onNewIntent(Intent intent){
    //called when a new intent for this class is created.
    // The main case is when the app was in background, a notification arrives to the tray, and the user touches the notification

    super.onNewIntent(intent);

    Log.d(Application.APPTAG, "onNewIntent - starting");
    Bundle extras = intent.getExtras();
    if (extras != null) {
        for (String key : extras.keySet()) {
            Object value = extras.get(key);
            Log.d(Application.APPTAG, "Extras received at onNewIntent:  Key: " + key + " Value: " + value);
        }
        String title = extras.getString("title");
        String message = extras.getString("body");
        if (message!=null && message.length()>0) {
            getIntent().removeExtra("body");
            showNotificationInADialog(title, message);
        }
    }
}


private void showNotificationInADialog(String title, String message) {

    // show a dialog with the provided title and message
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();
}

3- इस तरह से MyFirebase क्लास बनाएं:

package com.yourcompany.app;

import android.content.Intent;
import android.util.Log;

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

public class MyFirebaseMessagingService extends FirebaseMessagingService {


    public MyFirebaseMessagingService() {
        super();
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        Log.d(Application.APPTAG, "myFirebaseMessagingService - onMessageReceived - message: " + remoteMessage);

        Intent dialogIntent = new Intent(this, NotificationActivity.class);
        dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        dialogIntent.putExtra("msg", remoteMessage);
        startActivity(dialogIntent);

    }

}

4- इस तरह एक नया वर्ग NotificationActivity.class बनाएं:

package com.yourcompany.app;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper;

import com.google.firebase.messaging.RemoteMessage;

public class NotificationActivity extends AppCompatActivity {

private Activity context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    Bundle extras = getIntent().getExtras();

    Log.d(Application.APPTAG, "NotificationActivity - onCreate - extras: " + extras);

    if (extras == null) {
        context.finish();
        return;
    }

    RemoteMessage msg = (RemoteMessage) extras.get("msg");

    if (msg == null) {
        context.finish();
        return;
    }

    RemoteMessage.Notification notification = msg.getNotification();

    if (notification == null) {
        context.finish();
        return;
    }

    String dialogMessage;
    try {
        dialogMessage = notification.getBody();
    } catch (Exception e){
        context.finish();
        return;
    }
    String dialogTitle = notification.getTitle();
    if (dialogTitle == null || dialogTitle.length() == 0) {
        dialogTitle = "";
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(context, R.style.myDialog));
    builder.setTitle(dialogTitle);
    builder.setMessage(dialogMessage);
    builder.setPositiveButton(getResources().getString(R.string.accept), new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();

}

}

5- इन पंक्तियों को अपने टैग्स के अंदर, अपने ऐप मेनिफेस्ट में जोड़ें

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

    <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/>

    <activity android:name=".NotificationActivity"
        android:theme="@style/myDialog"> </activity>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/notification_icon"/>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/color_accent" />

6- इन पंक्तियों को अपने Application.java onCreate () विधि में, या MainActivity.class onCreate () विधि में जोड़ें:

      // notifications channel creation
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      // Create channel to show notifications.
      String channelId = getResources().getString("default_channel_id");
      String channelName = getResources().getString("General announcements");
      NotificationManager notificationManager = getSystemService(NotificationManager.class);
      notificationManager.createNotificationChannel(new NotificationChannel(channelId,
              channelName, NotificationManager.IMPORTANCE_LOW));
  }

किया हुआ।

अब इसके लिए 3 उल्लिखित परिदृश्यों में अच्छी तरह से काम करने के लिए, आपको निम्नलिखित तरीके से फायरबेस वेब कंसोल से अधिसूचना भेजनी होगी:

अधिसूचना अनुभाग में: अधिसूचना शीर्षक = अधिसूचना संवाद में प्रदर्शित करने के लिए शीर्षक (वैकल्पिक) अधिसूचना पाठ = उपयोगकर्ता को दिखाने के लिए संदेश (आवश्यक) फिर लक्ष्य अनुभाग में: ऐप = आपका एंड्रॉइड ऐप और अतिरिक्त विकल्प अनुभाग में: Android अधिसूचना चैनल = default_channel_id कस्टम डेटा कुंजी: शीर्षक मान: (अधिसूचना अनुभाग के शीर्षक क्षेत्र की तुलना में यहाँ एक ही पाठ) कुंजी: शरीर का मूल्य: (अधिसूचना अनुभाग के संदेश क्षेत्र की तुलना में यहाँ एक ही पाठ) कुंजी: click_action मान: .MainActivity ध्वनि। = विकलांग की
समाप्ति = 4 सप्ताह

आप Google Play के साथ एपीआई 28 के साथ एमुलेटर में इसे डिबग कर सकते हैं।

हैप्पी कोडिंग!


2
इस बेहतरीन जवाब के लिए धन्यवाद।
एलेक्स चेंगलान

@alvaro, जब मैं अधिसूचना प्राप्त मैं यूआरएल को खोलने के लिए चाहते हैं, तो मैं यह कैसे संभाल कर सकते हैं
engmms

ऐप के करीब या मारे जाने पर विवो opp फोन में काम नहीं करना
Android डेवलपर

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

2
यह अब तक का सबसे जवाब है, क्योंकि फायरबेस डॉक्यूमेंटेशन अब पढ़ता है: जब आपका ऐप बैकग्राउंड में होता है, तो एंड्रॉइड नोटिफिकेशन मैसेज को सिस्टम ट्रे में भेज देता है। अधिसूचना पर एक उपयोगकर्ता टैप डिफ़ॉल्ट रूप से ऐप लॉन्चर खोलता है। इसमें वे संदेश शामिल हैं जिनमें अधिसूचना और डेटा पेलोड दोनों शामिल हैं। इन मामलों में, अधिसूचना डिवाइस के सिस्टम ट्रे में वितरित की जाती है, और डेटा पेलोड को आपके लॉन्चर गतिविधि के इरादे के अतिरिक्त में दिया जाता है। ( firebase.google.com/docs/cloud-messaging/android/… ) इतने पुराने जवाब पुराने हैं
Riot Goes Woof

20

चूँकि display-messagesजो Firebase Notification UI से भेजे गए हैं वे केवल तभी काम करते हैं जब आपका ऐप अग्रभूमि में हो। इसके लिए data-messages, FCM को POST कॉल करने की आवश्यकता है

कदम

  1. उन्नत रेस्ट क्लाइंट Google क्रोम एक्सटेंशन इंस्टॉल करें यहां छवि विवरण दर्ज करें

  2. निम्नलिखित शीर्ष लेख जोड़ें

    कुंजी : सामग्री-प्रकार, मूल्य : आवेदन / json

    कुंजी : प्राधिकरण, मूल्य : कुंजी = "आपका सर्वर कुंजी" यहां छवि विवरण दर्ज करें

  3. शरीर को जोड़ो

    • यदि विषयों का उपयोग कर रहा है:

      {
          "to" : "/topics/topic_name",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
          }
      }
    • यदि पंजीकरण आईडी का उपयोग कर रहे हैं:

      {
          "registration_ids" : "[{"id"},{id1}]",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
           }
      }

बस!। अब onMessageReceivedहमेशा की तरह कॉलबैक सुनें ।

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}

20

संदेश को पृष्ठभूमि में कैप्चर करने के लिए आपको एक का उपयोग करने की आवश्यकता है BroadcastReceiver

import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.legacy.content.WakefulBroadcastReceiver
import com.google.firebase.messaging.RemoteMessage

class FirebaseBroadcastReceiver : WakefulBroadcastReceiver() {

    val TAG: String = FirebaseBroadcastReceiver::class.java.simpleName

    override fun onReceive(context: Context, intent: Intent) {

        val dataBundle = intent.extras
        if (dataBundle != null)
            for (key in dataBundle.keySet()) {
                Log.d(TAG, "dataBundle: " + key + " : " + dataBundle.get(key))
            }
        val remoteMessage = RemoteMessage(dataBundle)
        }
    }

और इसे अपने प्रकटन में जोड़ें:

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

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

फिलहाल काम नहीं कर रहा है, इसलिए मैं इस समाधान का प्रस्ताव दे रहा हूं। Google Bugbase पर एक दर्ज बग है। आप इसे देखना चाहते हैं।
रोमुलानो

क्या आप कृपया यहाँ बग का लिंक पोस्ट कर सकते हैं
गैलिया

अधिसूचना से डेटा कैसे प्राप्त करें?
रवि वाघेला

ऐप के मारे जाने पर यह स्पष्ट रूप से काम नहीं कर रहा है। मैंने घंटों तक इस समाधान की कोशिश की है। किसी कारण से एप्लिकेशन बैकग्राउंड में है और ऐप के मारे जाने पर ऐप काम नहीं कर रहा है
XcodeNOOB

16
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}

हर बार यह नहीं कहा जाता है कि यह केवल तभी कहा जाता है जब ऐप फोरग्राउंड में हो

हर बार इस पद्धति को ओवरराइड विधि कहा जाता है, चाहे कोई भी ऐप अग्रभूमि में या पृष्ठभूमि में हो या मार दिया गया हो, लेकिन यह विधि इस फ़ायरबेस एपी संस्करण के साथ उपलब्ध है

यह वह संस्करण है जिसे यूपीएल से आयात किया जाना है

compile 'com.google.firebase:firebase-messaging:10.2.1'

यह विधि है

@Override
public void handleIntent(Intent intent) {
    super.handleIntent(intent);

    // you can get ur data here 
    //intent.getExtras().get("your_data_key") 


}

पिछले फायरबेस एप के साथ यह तरीका ऐसा नहीं था, जब ऐप बैकग्राउंड में होने पर फायर बेस खुद को संभाल लेता है .... अब यू के पास यह तरीका है कि आप कभी भी क्या करना चाहते हैं ... यू इसे इस तरीके से कर सकते हैं .. ...

यदि आप पिछले संस्करण का उपयोग कर रहे हैं, तो डिफ़ॉल्ट गतिविधि उस स्थिति में शुरू हो जाएगी जब यू को उसी तरह डेटा मिल सकता है

if(getIntent().getExtras() != null && getIntent().getExtras().get("your_data_key") != null) {
String strNotificaiton = getIntent().getExtras().get("your_data_key").toString();

// क्या तुम कभी चाहते हो ....}

आम तौर पर यह सर्वर से संरचना होती है जो हमें अधिसूचना में मिलती है

{
    "notification": {
        "body": "Cool offers. Get them before expiring!",
        "title": "Flat 80% discount",
        "icon": "appicon",
        "click_action": "activity name" //optional if required.....
    },
    "data": {
        "product_id": 11,
        "product_details": "details.....",
        "other_info": "......."
    }
}

यह यू पर निर्भर है कि आप उस डेटा कुंजी को कैसे देना चाहते हैं या यू नोटिफिकेशन देना चाहते हैं और कुछ भी यू दे सकते हैं ....... जो कभी यू यहां देगा उसी कुंजी के साथ आपको वह डेटा मिलेगा ........ ।

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


मैंने 10.2.1 को फायरबेस-मैसेजिंग को अपडेट किया, सूचना संदेश में डेटा जोड़ा, और यह काम किया। अग्रभूमि, पृष्ठभूमि, और मार डाला। धन्यवाद
फ़िरस श्रौरौ

कोटलिन में, मुझे यह त्रुटि मिलती है: (44, 5) 'FireBaseMessagingService' में 'handleIntent' अंतिम है और इसे ओवरराइड नहीं किया जा सकता है
ugali soft


14

डॉक्स के अनुसार: 17 मई, 2017

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

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

तो, आपको पेलोड अधिसूचना + डेटा दोनों का उपयोग करना चाहिए:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

Click_action का उपयोग करने की कोई आवश्यकता नहीं है। आपको केवल LAUNCHER गतिविधि पर इरादे से एक्स्ट्रा प्राप्त करना चाहिए

<activity android:name=".MainActivity">
        <intent-filter>
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>

MainActivity पर जावा कोड ऑनक्रिएट विधि पर होना चाहिए:

Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
    Bundle extras = intent.getExtras();
    String someData= extras.getString("someData");
    String someData2 = extras.getString("someData2");
}

आप Firebase Notifications कंसोल से पेलोड अधिसूचना + डेटा दोनों का परीक्षण कर सकते हैं । उन्नत विकल्प अनुभाग पर कस्टम डेटा फ़ील्ड भरना न भूलें


13

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

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

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

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

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

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

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



8

इस तरह सरल सारांश

  • अगर आपका ऐप चल रहा है;

    onMessageReceived()

ट्रिगर है।

  • अगर आपका ऐप नहीं चल रहा है (स्वाइप करके मारा गया);

    onMessageReceived()

ट्रिगर नहीं किया जाता है और direclty द्वारा वितरित किया जाता है। यदि आपके पास कोई विशेष की-वैल्यू जोड़ी है। वे onMessageReceived () काम नहीं कर रहे हैं।

मैं इस तरह से मिला;

अपनी लॉन्चर गतिविधि में, यह तर्क डालें,

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState, R.layout.activity_splash);

    if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("PACKAGE_NAME")) {

        // do what you want

        // and this for killing app if we dont want to start
        android.os.Process.killProcess(android.os.Process.myPid());

    } else {

        //continue to app
    }
}

इस में अगर ब्लॉक, फायरबस यूआई के अनुसार अपनी कुंजी खोजें।

इस उदाहरण में मेरी कुंजी और मूल्य ऊपर की तरह; (भाषा के लिए खेद है =)) यहां छवि विवरण दर्ज करें

जब मेरा कोड काम करता है, तो मुझे "com.rda.note" मिलता है।

android.os.Process.killProcess(android.os.Process.myPid());

कोड की इस पंक्ति के साथ, मैंने अपना एप्लिकेशन बंद कर दिया और Google Play Market को खोल दिया

खुश कोडिंग =)


6

मैंने परिदृश्यों का पता लगाया,

जब अनुप्रयोग में है अग्रभूमि , onMessageReceived () विधि से कहा जाता है FirebaseService तो pendingIntent सेवा वर्ग में परिभाषित बुलाया जाएगा।

और जब ऐप बैकग्राउंड में होता है , तो पहली गतिविधि को कहा जाता है।

अब, यदि आप एक स्प्लैश गतिविधि का उपयोग करते हैं , तो ध्यान रखना चाहिए कि स्प्लैशशिविटी कहलाएगी , अन्यथा यदि स्प्लैश एक्टिविटी नहीं है, तो जो भी पहली गतिविधि है, उसे कॉल किया जाएगा।

तो फिर तुम जांच करने की आवश्यकता getIntent () की firstActivity अगर यह किसी भी देखने के लिए बंडल है.अगर सब कुछ है ठीक आप बंडल में भरा मूल्यों के साथ है देखेंगे। अगर में मूल्य डेटा टैग इस तरह सर्वर दिखता से भेजे गए,

"data": {
    "user_name": "arefin sajib",
    "value": "user name notification"
  }

फिर पहली गतिविधि में, आप देखेंगे, एक वैध आशय है ( getIntent () शून्य नहीं है ), वैध बंडल और अंदर बंडल, कुंजी के रूप में डेटा के साथ ऊपर उल्लेखित पूरे JSON होगा ।

इस परिदृश्य के लिए, मान के निष्कर्षण के लिए कोड इस तरह दिखेगा,

    if(getIntent()!=null){
            Bundle bundle = getIntent().getExtras();
            if (bundle != null) {
                try {
                   JSONObject object = new JSONObject(bundle.getStringExtra("data"));
String user_name = object.optString("user_name");

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
        }

3

आपके उत्तर के लिए आप सभी का धन्यवाद। लेकिन मैंने नोटिफिकेशन भेजने के बजाय डेटा मैसेज भेजकर इसे हल किया । सर्वर कोड

<?php
$url = "https://fcm.googleapis.com/fcm/send";
$token = "C-l6T_a7HouUK****";
$serverKey = "AAAAaOcKS00:********";
define( 'API_ACCESS_KEY', $serverKey );
$registrationIds = array($token);
// prep the bundle

$msg = array

(
 'message'  => 'here is a message. message',
 'title'        => 'This is a title. title',
 'subtitle' => 'This is a subtitle. subtitle',
 'tickerText'   => 'Ticker text here...Ticker text here...Ticker text 
 here',
 'vibrate'  => 1,
 'sound'        => 1,
 'largeIcon'    => 'large_icon',
 'smallIcon'    => 'small_icon'

);

$fields = array

(
  'registration_ids'    => $registrationIds,
  'data'            => $msg

);
$headers = array

(
  'Authorization: key=' . API_ACCESS_KEY,
 'Content-Type: application/json'

);


$ch = curl_init();

curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' 
);

curl_setopt( $ch,CURLOPT_POST, true );

curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );

curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );

curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );

curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );

$result = curl_exec($ch );

curl_close( $ch );

echo $result;

?>

और onMessageReceived में डेटा को पकड़ा

public class MyFirebaseMessagingService extends FirebaseMessagingService     {

  private static final String TAG = "MyFirebaseMsgService";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    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());

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


}
   private void sendNotification(String messageBody) {
    Intent intent = new Intent(this, Notify.class).putExtra("msg",messageBody);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    String channelId = "idddd";
    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(MyFirebaseMessagingService.this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("FCM Message")
                    .setContentText(messageBody)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}

1
यह एक पृष्ठभूमि के साथ भी काम कर रहा है?
तबीश खान

@ ताबिशखान हाँ भाई यह काम कर रहा है यदि आपके पास कोई समस्या है तो मुझे पूछने के लिए स्वतंत्र महसूस करें .. धन्यवाद
एंड्रॉइड सनाउल्लाह

1
hi @AndroidSanaullah, क्या आप पहले भाग को सर्वर कोड के बारे में बता सकते हैं, जहाँ आप वास्तव में इसे डालते हैं, मैं उसी मुद्दे का सामना कर रहा हूँ, लेकिन मैं सर्वर के हिस्से को काफी नहीं समझता, क्या आप पोस्टमैन का उपयोग कर रहे हैं?
Shid

अनुरोध के लिए कर्ल का उपयोग किया जाता है और इसके लिए सभी मापदंडों को पारित किया जाता है। @ Shid
Android Sanaullah

2

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

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

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

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

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

और इसी तरह आप किसी भी डेटा को प्राप्त कर सकते हैं जिसे आपने सर्वर से भेजा है onMessageReceived()


2

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

बाकी क्लाइंट टूल लिंक: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnfgcellkdfbfbjeloo

इस url का उपयोग करें: - https://fcm.googleapis.com/fcm/send सामग्री-प्रकार: अनुप्रयोग / json प्राधिकरण: कुंजी = आपका सर्वर कुंजी या स्वतः-कुंजी कुंजी (रेफरी नीचे देखें)

{ "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"
}

प्राधिकरण कुंजी Google डेवलपर्स कंसोल पर जाकर प्राप्त की जा सकती है और अपनी परियोजना के लिए बाएं मेनू पर क्रेडेंशियल बटन पर क्लिक करें। सूचीबद्ध एपीआई कुंजी के बीच, सर्वर कुंजी आपकी प्राधिकरण कुंजी होगी।

और आपको एपीआई का उपयोग करके भेजे गए अपने पोस्ट अनुरोध के "टू" अनुभाग में रिसीवर के टोकन को डालना होगा।


2

आप onMessageReceived (RemoteMessage RemoteMessage) को पृष्ठभूमि में काम करना चाहते हैं, केवल डेटा भाग सूचना भेजें:

"data":    "image": "",    "message": "Firebase Push Message Using API", 

"अन्यता": "सत्य", "टू": "डिवाइस आईडी या डिवाइस टोकन"

इसके द्वारा onMessageRecivied कॉल बैकग्राउंड और फोरग्राउंड है जिसे आपके लॉन्चर एक्टिविटी पर नोटिफिकेशन ट्रे का उपयोग करके नोटिफिकेशन को संभालने की कोई आवश्यकता नहीं है। इसका उपयोग करने में डेटा पेलोड संभालें:

  public void onMessageReceived(RemoteMessage remoteMessage)
    if (remoteMessage.getData().size() > 0) 
    Log.d(TAG, "Message data payload: " + remoteMessage.getData());      

1

जून 2018 उत्तर -

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

क्लाउड फ़ंक्शंस का उपयोग करना:

const message = {
    token: token_id,   // obtain device token id by querying data in firebase
    data: {
       title: "my_custom_title",
       body:  "my_custom_body_message"
       }
    }


return admin.messaging().send(message).then(response => {
    // handle response
});

फिर अपने onMessageReceived () में, अपनी कक्षा में com.google.firebase.messaging.FirebaseMessagingService का विस्तार करते हुए:

if (data != null) {
  Log.d(TAG, "data title is: " + data.get("title");
  Log.d(TAG, "data body is: " + data.get("body");
}

// build notification using the body, title, and whatever else you want.

क्या आपके पास कोई स्रोत है, क्या यह सुरक्षित है?
योगेश राठी

यह सुरक्षित है, मैं इसका उपयोग अपने ऐप्स में करता हूं। हालांकि, पोस्टिंग के 6 महीने बाद, मैं स्रोत को याद नहीं रख सकता - मुझे लगता है कि यह फायरबेस डॉक्यूमेंटेशन है।
जेफ पडगेट

1

OAUTH 2.0 के अनुसार:

OAUTH 2 का उपयोग करके अब इस मामले के लिए बीसीक्यूसी FCM की प्रामाणिक समस्या होगी

इसलिए मैंने फायरबेस डॉक्यूमेंटेशन पढ़ा और डॉक्यूमेंटेशन के अनुसार डेटा मैसेज पोस्ट करने का नया तरीका है;

POST: https://fcm.googleapis.com/v1/projects/YOUR_FIREBASEDB_ID/messages:send

हेडर

Key: Content-Type, Value: application/json

प्रमाणीकरण

Bearer YOUR_TOKEN 

उदाहरण बॉडी

{
   "message":{
    "topic" : "xxx",
    "data" : {
         "body" : "This is a Firebase Cloud Messaging Topic Message!",
         "title" : "FCM Message"
          }
      }
 }

Url में डेटाबेस Id है जिसे आप अपने फायरबेस कंसोल पर पा सकते हैं। (प्रोजेक्ट सेटिटिंग्स पर जाएं)

और अब हमारा टोकन ले सकते हैं (यह केवल 1 घंटा मान्य होगा):

फायरबेस कंसोल में सबसे पहले, सेटिंग्स> सेवा खाते खोलें । नई निजी कुंजी जनरेट करें पर क्लिक करें , JSON फ़ाइल को सुरक्षित रूप से कुंजी के साथ संग्रहीत करें। मुझे मैन्युअल रूप से सर्वर अनुरोधों को अधिकृत करने के लिए इस JSON फ़ाइल की आवश्यकता थी। मैंने इसे डाउनलोड किया।

फिर मैं एक नोड.जेएस प्रोजेक्ट बनाता हूं और इस फ़ंक्शन का उपयोग अपने टोकन प्राप्त करने के लिए करता हूं;

var PROJECT_ID = 'YOUR_PROJECT_ID';
var HOST = 'fcm.googleapis.com';
var PATH = '/v1/projects/' + PROJECT_ID + '/messages:send';
var MESSAGING_SCOPE = 'https://www.googleapis.com/auth/firebase.messaging';
var SCOPES = [MESSAGING_SCOPE];

  router.get('/', function(req, res, next) {
      res.render('index', { title: 'Express' });
      getAccessToken().then(function(accessToken) {
        console.log("TOKEN: "+accessToken)
      })

    });

function getAccessToken() {
return new Promise(function(resolve, reject) {
    var key = require('./YOUR_DOWNLOADED_JSON_FILE.json');
    var jwtClient = new google.auth.JWT(
        key.client_email,
        null,
        key.private_key,
        SCOPES,
        null
    );
    jwtClient.authorize(function(err, tokens) {
        if (err) {
            reject(err);
            return;
        }
        resolve(tokens.access_token);
    });
});
}

अब मैं अपने पोस्ट अनुरोध में इस टोकन का उपयोग कर सकता हूं। तब मैं अपना डेटा संदेश पोस्ट करता हूं, और अब यह मेरे ऐप्स onMessageReceived फ़ंक्शन द्वारा नियंत्रित किया जाता है।


स्वीकृत उत्तर काम कर रहा है, बैरर टोकन टोकन तरीका नहीं है, आपको इसे पोस्टमैन के साथ आज़माने के लिए पढ़ने की ज़रूरत है: stackoverflow.com/questions/45309674/…
कार्लोस जीसस अरनियासिया तबगोर्गा

1

2019 के बाद से, Google Firebase ने अपने एपीआई I में एक बड़ा बदलाव किया है: 'com.google.firebase:firebase-messaging:18.0.0'

18.0.0 में उन्होंने हटा दिया MyFirebaseInstanceIDServiceऔर आपको टोकन प्राप्त करने की आवश्यकता है, MyFirebaseMessagingServiceइसलिए आपको केवल लिखने की आवश्यकता है:

@Override
public void onNewToken(String token) {
    Log.d(TAG, "Refreshed token: " + token);

}

और आपके AndroidManifest.xml में भी, आपको निकालना होगा:

<service android:name=".service.MyFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

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

कस्टम डिफ़ॉल्ट आइकन और कस्टम रंग सेट करने के लिए एप्लिकेशन टैग के अंदर इन पंक्तियों को जोड़ें:

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_notification" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/push_channel" />

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

उदाहरण के लिए, यदि आपका जसन इस प्रकार है:

 "data": {
"message": "2",
"title": "1",
"pushType" : "banner",
"bannerLink": "http://www.google.com",
"image" : "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"}

आपको बस उन मूल्यों को प्राप्त करने के लिए एक सरल इरादे लिखने की आवश्यकता है:

        Bundle extras = intent.getExtras();
        String bannerLink = extras.getString("bannerLink");
        ...
        String channelId = extras.getString("channelId");

0

उपरोक्त उत्तरों के अलावा, यदि आप FCM कंसोल का उपयोग करके पुश नोटिफिकेशन का परीक्षण कर रहे हैं, तो पुश नोटिफिकेशन बंडल में 'डेटा' कुंजी और ऑब्जेक्ट नहीं जोड़ा जाता है। इसलिए जब ऐप बैकग्राउंड या मारी जाएगी तो आपको विस्तृत पुश नोटिफिकेशन नहीं मिलेगा।

इस स्थिति में आपको ऐप बैकग्राउंड परिदृश्य का परीक्षण करने के लिए अपने बैक एंड एडमिन कंसोल का विकल्प चुनना होगा।

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


0

इस कोड का उपयोग करके आप पृष्ठभूमि / अग्रभूमि में सूचना प्राप्त कर सकते हैं और कार्रवाई भी कर सकते हैं:

//Data should come in this format from the notification
{
  "to": "/xyz/Notifications",
  "data": {
      "key1": "title notification",
      "key2": "description notification"
  }
}

इन-ऐप इस कोड का उपयोग करें:

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
      String key1Data = remoteMessage.getData().get("key1");
      // use key1Data to according to your need
    }

// डेटा को इस प्रारूप में अधिसूचना {"से": "/ xyz / सूचना", "डेटा": {"की 1": "शीर्षक अधिसूचना", "की 2": "विवरण अधिसूचना"}} से आना चाहिए। php सेवा में यह कोड?
तबीश खान

-3

दो तरह के नोटिफिकेशन होंगे

  1. डिस्प्ले नोटिफिकेशन - केवल डिस्प्ले नोटिफिकेशन, दिखाया जाएगा केवल ऐप ओपन नहीं है और ऐप स्टैक में है।
  2. डेटा नोटिफिकेशन - कॉलबैक ऑन-मेसेजरेजेसिव मेथड ऑफ फायरबसमेस्सैगिंगसेवर में जाएगा और यह तब काम करता है जब ऐप बैकग्राउंड, फोरग्राउंड या मारे गए स्टेट में हो।

जब अनुप्रयोग पृष्ठभूमि में हो, तो आपको सूचना को संभालने के लिए डेटा सूचनाओं का उपयोग करना चाहिए।


-5

मैंने एक ही समस्या का अनुभव किया है और फायरबेस लाइब्रेरी को फिर से शुरू किया है और जब एप्लिकेशन बैकग्राउंड में होता है तो नोटिफिकेशन भेजने से रोकता है

* पुस्तकालय https://github.com/erdalceylan/com-google-firebase-messaging

 dependencies {
        compile 'com.google.firebase:firebase-core:11.2.0'
        compile 'com.github.erdalceylan:com-google-firebase-messaging:v1-11.2.0'
    }

*

@WorkerThread
public void onMessageReceived(RemoteMessage var1) {
  //your app is in background or foreground all time calling
}

आशा मदद करती है। सौभाग्य


2
उपयोगी उत्तर नहीं
अंकित पाटीदार

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