Helpex - Trao đổi & giúp đỡ Đăng nhập
317

Đây là bảng kê khai của tôi

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

Khi ứng dụng ở chế độ nền và thông báo đến thì thông báo mặc định sẽ đến và không chạy mã của tôi onMessageReceived.

Đây là onMessageReceivedcủa tôi . Điều này gọi nếu ứng dụng của tôi đang chạy trên nền trước, không phải khi ứng dụng ở chế độ nền. Làm thế nào để chạy mã này khi ứng dụng ở chế độ nền?

// [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]
317 hữu ích 3 bình luận 247k xem chia sẻ
21 trả lời 21
538

1. Tại sao điều này xảy ra?

Có hai loại tin nhắn trong FCM (Firebase Cloud Messaging):

  1. Hiển thị tin nhắn : Những tin nhắn này chỉ kích hoạt cuộc onMessageReceived()gọi lại khi ứng dụng của bạn ở phía trước
  2. Tin nhắn dữ liệu : Tin nhắn luận án kích hoạt cuộc onMessageReceived()gọi lại ngay cả khi ứng dụng của bạn ở nền trước / nền / bị giết

Đội ngũ Firebase chưa phát triển giao diện người dùng để gửi data-messagesđến thiết bị của bạn.

2. Làm thế nào để?

Để đạt được điều này, bạn phải thực hiện một POSTyêu cầu tới URL sau:

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

Tiêu đề

  • Khóa : Content-Type , Giá trị: application/json
  • Khóa : Authorization , Giá trị: key=<your-server-key>

Cơ thể sử dụng chủ đề

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

Hoặc nếu bạn muốn gửi nó đến các thiết bị cụ thể

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


LƯU Ý: Đảm bảo bạn không thêm khóa JSON notification
LƯU Ý: Để lấy khóa máy chủ của bạn, bạn có thể tìm thấy nó trong bảng điều khiển firebase:Your project -> settings -> Project settings -> Cloud messaging -> Server Key

3. Làm thế nào để xử lý tin nhắn thông báo đẩy?

Đây là cách bạn xử lý tin nhắn nhận được:

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

     // Manage data
}
538 hữu ích 5 bình luận chia sẻ
130

Để tạo thư viện firebase, hãy gọi onMessageReceured () của bạn trong các trường hợp sau

  1. Ứng dụng ở phía trước
  2. Ứng dụng trong nền
  3. Ứng dụng đã bị giết

bạn không được đặt khóa JSON 'thông báo' trong yêu cầu của mình vào API firebase mà thay vào đó hãy sử dụng 'dữ liệu', xem bên dưới.

Thông báo sau sẽ không gọi onMessageReceured () của bạn khi ứng dụng của bạn ở chế độ nền hoặc bị giết và bạn không thể tùy chỉnh thông báo của mình.

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

nhưng thay vì sử dụng nó sẽ hoạt động

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

Về cơ bản, thông báo được gửi trong đối số RemoteMessage cùng với đối tượng dữ liệu của bạn dưới dạng Bản đồ, sau đó bạn có thể quản lý thông báo trong onMessageReceured như trong đoạn trích ở đây

@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
    */
}
130 hữu ích 5 bình luận chia sẻ
77

Tôi cảm thấy như tất cả các phản hồi không đầy đủ nhưng tất cả chúng đều có thứ bạn cần xử lý thông báo có dữ liệu khi ứng dụng của bạn ở chế độ nền.

Thực hiện theo các bước sau và bạn sẽ có thể xử lý thông báo của mình khi ứng dụng của bạn ở chế độ nền.

1.Thêm một bộ lọc ý định như thế này:

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

đến một hoạt động mà bạn muốn xử lý dữ liệu thông báo.

  1. Gửi thông báo với định dạng tiếp theo:

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

Chìa khóa ở đây là thêm

"click_action" : ".MainActivity"

trong đó .MainActivity là hoạt động với bộ lọc ý định mà bạn đã thêm trong bước 1.

  1. Nhận thông tin "dữ liệu" từ thông báo trong onCreate của ".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
        }
    }

Và đó nên là tất cả những gì bạn cần làm. Tôi hi vọng nó sẽ giúp ích cho mọi người :)

77 hữu ích 5 bình luận chia sẻ
31

Theo tài liệu

Xử lý tin nhắn trong ứng dụng chạy nền

Khi ứng dụng của bạn ở chế độ nền, Android sẽ chuyển các thông báo thông báo đến khay hệ thống. Một người dùng chạm vào thông báo sẽ mở trình khởi chạy ứng dụng theo mặc định.

Điều này bao gồm các tin nhắn có chứa cả thông báo và tải trọng dữ liệu. Trong những trường hợp này, thông báo được gửi đến khay hệ thống của thiết bị và tải trọng dữ liệu được gửi trong phần bổ sung cho mục đích của Hoạt động trình khởi chạy của bạn.

Nếu bạn muốn mở ứng dụng của mình và thực hiện một hành động cụ thể, hãy đặt click_action trong tải trọng thông báo và ánh xạ nó tới bộ lọc ý định trong Hoạt động bạn muốn khởi chạy. Ví dụ: đặt click_action thành OPEN_ACTIVITY_1 để kích hoạt bộ lọc ý định như sau:

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

Chỉnh sửa :

Dựa trên chủ đề này :

Bạn không thể đặt tải trọng click_action bằng Bảng điều khiển Firebase. Bạn có thể thử kiểm tra bằng lệnh curl hoặc máy chủ http tùy chỉnh

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\"}}"
31 hữu ích 5 bình luận chia sẻ
27

Theo tài liệu về căn cứ hỏa lực trong việc gửi xuôi dòng bằng cách sử dụng căn cứ hỏa lực , có 2 loại tải trọng:

  1. dữ liệu

    Tham số này chỉ định các cặp khóa-giá trị tùy chỉnh của tải trọng của thông báo. Ứng dụng khách có trách nhiệm xử lý tin nhắn dữ liệu. Thông điệp dữ liệu chỉ có các cặp khóa-giá trị tùy chỉnh.

  2. thông báo

    Tham số này chỉ định các cặp giá trị khóa-giá trị người dùng có thể nhìn thấy trước của tải trọng thông báo. FCM tự động hiển thị thông báo cho các thiết bị của người dùng cuối thay mặt cho ứng dụng khách. Thông báo thông báo có một bộ các khóa hiển thị được xác định trước.

Khi bạn ở trong nền trước, bạn có thể lấy dữ liệu bên trong FCM bằng cách sử dụng onMessageReceured () , bạn có thể lấy dữ liệu của mình từ tải trọng dữ liệu .

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

Khi bạn ở chế độ nền, FCM sẽ hiển thị thông báo trong khay hệ thống dựa trên thông tin từ tải trọng thông báo . Tiêu đề, tin nhắn và biểu tượng được sử dụng cho thông báo trên khay hệ thống được lấy từ tải trọng thông báo .

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

Tải trọng thông báo này được sử dụng khi bạn muốn tự động hiển thị thông báo trên khay hệ thống khi ứng dụng của bạn ở chế độ nền. Để nhận dữ liệu thông báo khi ứng dụng của bạn ở chế độ nền, bạn nên thêm click_action bên trong tải trọng thông báo .

Nếu bạn muốn mở ứng dụng của mình và thực hiện một hành động cụ thể [trong khi được nền], hãy đặt click_action trong tải trọng thông báo và ánh xạ nó tới bộ lọc ý định trong Hoạt động bạn muốn khởi chạy. Ví dụ: đặt click_action thành OPEN_ACTIVITY_1 để kích hoạt bộ lọc ý định như sau:

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

Đặt bộ lọc ý định đó vào bảng kê khai của bạn, bên trong thẻ ứng dụng. Khi bạn nhấp vào thông báo, nó sẽ mở ứng dụng và đi thẳng đến hoạt động mà bạn xác định trong click_action, trong trường hợp này là "OPEN_ACTIVTY_1". Và bên trong hoạt động đó bạn có thể lấy dữ liệu bằng cách:

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

Tôi đang sử dụng FCM cho ứng dụng Android của mình và sử dụng cả hai trọng tải. Dưới đây là ví dụ JSON tôi đang sử dụng:

{
  "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"
   }
}
27 hữu ích 4 bình luận chia sẻ
20

display-messagesgiao diện được gửi từ UI Thông báo Firebase chỉ hoạt động nếu ứng dụng của bạn ở phía trước. data-messages, cần phải thực hiện một cuộc gọi POST đến FCM

Các bước

  1. Cài đặt phần mở rộng phần còn lại của khách hàng Google Chrome Cách xử lý thông báo khi ứng dụng chạy nền trong Firebase?

  2. Thêm các tiêu đề sau

    Khóa : Loại nội dung, Giá trị : ứng dụng / json

    Khóa : Ủy quyền, Giá trị : key = "khóa máy chủ của bạn" Cách xử lý thông báo khi ứng dụng chạy nền trong Firebase?

  3. Thêm cơ thể

    • Nếu sử dụng các chủ đề:

      {
          "to" : "/topics/topic_name",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
          }
      }
    • Nếu sử dụng id đăng ký:

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

Đó là nó!. Bây giờ hãy nghe onMessageReceivedgọi lại như bình thường.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}
20 hữu ích 0 bình luận chia sẻ
16

Để chụp tin nhắn ở chế độ nền, bạn cần sử dụng BroadcastReceiver

public class FirebaseDataReceiver extends WakefulBroadcastReceiver {

    private final String TAG = "FirebaseDataReceiver";

    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "I'm in!!!");
        Bundle dataBundle = intent.getBundleExtra("data");
        Log.d(TAG, dataBundle.toString());
    }
}

và thêm nó vào bảng kê khai của bạn:

<receiver
      android:name="MY_PACKAGE_NAME.FirebaseDataReceiver"
      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>
16 hữu ích 5 bình luận chia sẻ
16
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}

không được gọi mỗi lần nó chỉ được gọi khi ứng dụng nằm trong khu vực

Có một phương thức ghi đè phương thức này được gọi mỗi lần, bất kể ứng dụng nào ở nền trước hoặc nền hoặc bị giết nhưng phương thức này có sẵn với phiên bản api firebase này

đây là phiên bản bạn phải nhập từ gradle

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

đây là phương pháp

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

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


}

với api firebase trước đây, phương pháp này không có ở đó nên trong trường hợp đó, cơ sở fire tự xử lý khi ứng dụng ở chế độ nền .... bây giờ bạn có phương thức này bất cứ khi nào bạn muốn làm ... bạn có thể thực hiện ở đây trong phương thức này .. ...

nếu bạn đang sử dụng phiên bản trước hơn hoạt động mặc định sẽ bắt đầu trong trường hợp đó bạn có thể nhận dữ liệu theo cách tương tự

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

// làm những gì bạn muốn ....}

nói chung đây là cấu trúc từ máy chủ mà chúng tôi nhận được trong thông báo

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

tùy thuộc vào cách bạn muốn cung cấp khóa dữ liệu đó hoặc bạn muốn thông báo bất cứ điều gì bạn có thể cung cấp ....... những gì bạn sẽ cung cấp ở đây với cùng một khóa bạn sẽ nhận được dữ liệu đó ........ .

Có một vài trường hợp nếu bạn không gửi hành động nhấp trong trường hợp đó khi bạn nhấp vào thông báo hoạt động mặc định sẽ mở, nhưng nếu bạn muốn mở hoạt động cụ thể của mình khi ứng dụng ở chế độ nền, bạn có thể gọi hoạt động của mình từ phương thức này trên phương thức handleIntent vì điều này được gọi mỗi lần

16 hữu ích 3 bình luận chia sẻ
13

Dưới đây là các khái niệm rõ ràng hơn về thông điệp firebase. Tôi tìm thấy nó từ nhóm hỗ trợ của họ.

Firebase có ba loại thông báo :

Tin nhắn thông báo : Tin nhắn thông báo hoạt động trên nền hoặc tiền cảnh. Khi ứng dụng ở chế độ nền, thông báo Thông báo sẽ được gửi đến khay hệ thống. Nếu ứng dụng ở phía trước, tin nhắn được xử lý bởi onMessageReceived()hoặc didReceiveRemoteNotificationgọi lại. Đây là những gì cơ bản được gọi là hiển thị tin nhắn.

Tin nhắn dữ liệu : Trên nền tảng Android, tin nhắn dữ liệu có thể hoạt động trên nền và tiền cảnh. Thông báo dữ liệu sẽ được xử lý bởi onMessageReceured (). Một lưu ý cụ thể về nền tảng ở đây sẽ là: Trên Android, tải trọng dữ liệu có thể được truy xuất trong Mục đích được sử dụng để khởi chạy hoạt động của bạn. Để xây dựng, nếu bạn có "click_action":"launch_Activity_1", bạn có thể lấy mục đích này thông qua getIntent()từ chỉ Activity_1.

Tin nhắn có cả tải thông báo và tải dữ liệu : Khi ở chế độ nền, ứng dụng sẽ nhận được tải thông báo trong khay thông báo và chỉ xử lý tải trọng dữ liệu khi người dùng chạm vào thông báo. Khi ở phía trước, ứng dụng của bạn sẽ nhận được một đối tượng tin nhắn với cả hai tải trọng có sẵn. Thứ hai, click_actiontham số thường được sử dụng trong tải trọng thông báo và không phải trong tải trọng dữ liệu. Nếu được sử dụng bên trong tải trọng dữ liệu, tham số này sẽ được coi là cặp khóa-giá trị tùy chỉnh và do đó bạn sẽ cần triển khai logic tùy chỉnh để nó hoạt động như dự định.

Ngoài ra, tôi khuyên bạn nên sử dụng onMessageReceivedphương thức (xem Thông báo dữ liệu) để trích xuất gói dữ liệu. Từ logic của bạn, tôi đã kiểm tra đối tượng gói và không tìm thấy nội dung dữ liệu dự kiến. Dưới đây là một tham chiếu đến một trường hợp tương tự có thể cung cấp rõ ràng hơn.

Để biết thêm thông tin truy cập chủ đề này của tôi

13 hữu ích 0 bình luận chia sẻ
9

Cập nhật câu trả lời 2017

Đây là một câu trả lời rõ ràng từ các tài liệu liên quan đến điều này:

Cách xử lý thông báo khi ứng dụng chạy nền trong Firebase?

9 hữu ích 1 bình luận chia sẻ
9

Theo các tài liệu: ngày 17 tháng 5 năm 2017

Khi ứng dụng của bạn ở chế độ nền , Android sẽ chuyển các thông báo thông báo đến khay hệ thống. Một người dùng chạm vào thông báo sẽ mở trình khởi chạy ứng dụng theo mặc định .

Điều này bao gồm các tin nhắn chứa cả thông báo và tải trọng dữ liệu (và tất cả các tin nhắn được gửi từ bảng điều khiển Thông báo). Trong những trường hợp này, thông báo được gửi đến khay hệ thống của thiết bị và tải trọng dữ liệu được gửi trong phần bổ sung cho mục đích của Hoạt động trình khởi chạy của bạn.

Vì vậy, bạn nên sử dụng cả dữ liệu + thông báo tải trọng:

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

Không cần sử dụng click_action. Bạn chỉ nên lấy ý định từ hoạt động LAUNCHER

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

Mã Java phải là phương thức onCreate trên MainActivity:

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

Bạn có thể kiểm tra cả thông báo tải trọng + dữ liệu từ Bảng điều khiển thông báo Firebase . Đừng quên điền các trường dữ liệu tùy chỉnh vào phần Tùy chọn nâng cao

9 hữu ích 0 bình luận chia sẻ
6

Tóm tắt đơn giản như thế này

  • nếu ứng dụng của bạn đang chạy;

    onMessageReceived()

là tác nhân.

  • nếu ứng dụng của bạn không chạy (bị giết bằng cách vuốt);

    onMessageReceived()

không được kích hoạt và phân phối bởi direclty. Nếu bạn có bất kỳ cặp khóa-giá trị đặc biệt. Họ không làm việc vì beacuse onMessageReceured () không hoạt động.

Tôi đã tìm thấy cách này;

Trong hoạt động launcher của bạn, đặt logic này,

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

trong khối này nếu chặn, tìm kiếm các khóa của bạn theo UI firebase.

Trong ví dụ này, khóa và giá trị của tôi như trên; (xin lỗi vì ngôn ngữ =)) Cách xử lý thông báo khi ứng dụng chạy nền trong Firebase?

Khi mã của tôi hoạt động, tôi nhận được "com.rda.note".

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

với dòng mã này, tôi đã đóng ứng dụng của mình và mở Google Play Market

mã hóa hạnh phúc =)

6 hữu ích 0 bình luận chia sẻ
6

Tôi đã tìm ra các kịch bản,

Khi ứng dụng ở chế độ nền trước , phương thức onMessageReceured () được gọi từ FirebaseService . Vì vậy, chờ đợi được xác định trong lớp dịch vụ sẽ được gọi.

Và khi ứng dụng ở chế độ nền , hoạt động đầu tiên được gọi.

Bây giờ, nếu bạn sử dụng một hoạt động giật gân , thì phải nhớ rằng tính năng giật gân sẽ được gọi, nếu không có hoạt động giật gân , thì bất cứ hoạt động đầu tiên nào cũng sẽ được gọi.

Sau đó, bạn cần kiểm tra getIntent () của FirstActivity để xem nó có gói nào không . Nếu mọi thứ đều ổn, bạn sẽ thấy gói có ở đó với các giá trị được điền vào. Nếu giá trị trong thẻ dữ liệu được gửi từ máy chủ trông như thế này,

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

Sau đó, trong hoạt động đầu tiên, bạn sẽ thấy, có một mục đích hợp lệ ( getIntent () không phải là null ), gói hợp lệ và bên trong gói, sẽ có toàn bộ JSON được đề cập ở trên với dữ liệukhóa .

Đối với kịch bản này, mã trích xuất giá trị sẽ như thế này,

    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();
                }


            }
        }
6 hữu ích 0 bình luận chia sẻ
3

Cảm ơn tất cả các bạn đã trả lời. Nhưng tôi đã giải quyết điều này bằng cách gửi tin nhắn dữ liệu thay vì gửi Thông báo . Mã máy chủ

<?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;

?>

Và bắt được Dữ liệu trong onMessageReceured

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());
}
}
3 hữu ích 3 bình luận chia sẻ
2

Xóa hoàn toàn tải thông báo khỏi yêu cầu máy chủ của bạn. Chỉ gửi dữ liệu và xử lý nó onMessageReceived(), nếu không, onMessageReceivedứng dụng của bạn sẽ không được kích hoạt khi ứng dụng ở chế độ nền hoặc bị tắt.

Đây là những gì tôi đang gửi từ máy chủ:

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

Vì vậy, bạn có thể nhận dữ liệu của mình onMessageReceived(RemoteMessage message)như thế này: (giả sử tôi phải lấy id)

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

Và tương tự, bạn có thể nhận được bất kỳ dữ liệu nào bạn đã gửi từ máy chủ bên trong onMessageReceived().

2 hữu ích 0 bình luận chia sẻ
2

Cách dễ dàng để gửi tin nhắn ngay cả khi ứng dụng ở chế độ nền và tiền cảnh như sau: - Để gửi tin nhắn bằng API, bạn có thể sử dụng công cụ có tên AdvancedREST Client, tiện ích mở rộng chrome và gửi tin nhắn với các tham số sau.

Công cụ ứng dụng khách còn lại Liên kết: https://chrom.google.com.vn/webstore/detail/advified-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

sử dụng url này: - https://fcm.googleapis.com/fcm/send Loại nội dung: application / json Ủy quyền: key = Khóa máy chủ của bạn Từ hoặc khóa Authoization (xem bên dưới ref)

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

Có thể lấy khóa ủy quyền bằng cách truy cập bảng điều khiển dành cho nhà phát triển của Google và nhấp vào nút Thông tin xác thực ở menu bên trái cho dự án của bạn. Trong số các khóa API được liệt kê, khóa máy chủ sẽ là khóa ủy quyền của bạn.

Và bạn cần đặt mã thông báo của người nhận trong phần Rô-lô-lô của yêu cầu POST của bạn được gửi bằng API.

2 hữu ích 0 bình luận chia sẻ
1

Trả lời tháng 6 năm 2018 -

Bạn phải chắc chắn rằng không có từ khóa "thông báo" ở bất cứ đâu trong tin nhắn. Chỉ bao gồm "dữ liệu" và ứng dụng sẽ có thể xử lý tin nhắn trong onMessageReceured, ngay cả khi ở chế độ nền hoặc bị giết.

Sử dụng các chức năng đám mây:

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
});

Sau đó, trong onMessageReceured (), trong lớp của bạn mở rộng 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.
1 hữu ích 2 bình luận chia sẻ
1

bạn muốn làm việc trênMessageReceured (RemoteMessage remoteMessage) trong nền chỉ gửi phần thông báo phần dữ liệu này:

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

"AnotherActivity": "True", "to": "id thiết bị hoặc mã thông báo thiết bị"

Bởi điều này onMessageRecivied là nền cuộc gọi và tiền cảnh không cần xử lý thông báo bằng khay thông báo trên hoạt động trình khởi chạy của bạn. Xử lý tải trọng dữ liệu bằng cách sử dụng này:
void void onMessageReceured (RemoteMessage remoteMessage) if (remoteMessage.getData (). Size ()> 0) Log.d (TAG, "Tải dữ liệu tin nhắn:" + remoteMessage.getData ());

1 hữu ích 0 bình luận chia sẻ
1

Theo OAUTH 2.0:

Sẽ có vấn đề Auth cho trường hợp này beacuse FCM hiện đang sử dụng OAUTH 2

Vì vậy, tôi đọc tài liệu firebase và theo tài liệu cách mới để gửi thông điệp dữ liệu là;

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

Tiêu đề

Key: Content-Type, Value: application/json

Xác thực

Bearer YOUR_TOKEN 

Thân ví dụ

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

Trong url có Id cơ sở dữ liệu mà bạn có thể tìm thấy nó trên bảng điều khiển firebase. (Đi định cư dự án)

Và bây giờ, hãy lấy mã thông báo của chúng tôi (Nó sẽ chỉ có hiệu lực trong 1 giờ):

Đầu tiên trong bảng điều khiển Firebase, mở Cài đặt> Tài khoản dịch vụ . Nhấp vào Tạo khóa riêng mới , lưu trữ an toàn tệp JSON chứa khóa. Tôi cần tệp JSON này để ủy quyền các yêu cầu máy chủ theo cách thủ công. Tôi đã tải nó.

Sau đó, tôi tạo một dự án node.js và sử dụng chức năng này để nhận mã thông báo của mình;

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);
    });
});
}

Bây giờ tôi có thể sử dụng mã thông báo này trong yêu cầu bài viết của mình. Sau đó, tôi đăng thông báo dữ liệu của mình và hiện tại nó được xử lý bởi các ứng dụng của tôi trên chức năng onMessageReceured.

1 hữu ích 1 bình luận chia sẻ
0

Ngoài các câu trả lời ở trên, Nếu bạn đang kiểm tra thông báo đẩy bằng bảng điều khiển FCM , khóa và đối tượng 'dữ liệu' sẽ không được thêm vào gói Thông báo đẩy. Vì vậy, bạn sẽ không nhận được thông báo đẩy chi tiết khi Ứng dụng chạy nền hoặc bị tắt.

Trong trường hợp này, bạn phải chọn cho bảng điều khiển quản trị viên phía sau để kiểm tra kịch bản nền Ứng dụng.

Tại đây, bạn sẽ thêm khóa 'dữ liệu' vào gói đẩy của mình. vì vậy, đẩy chi tiết sẽ được hiển thị như mong đợi. Hy vọng điều này sẽ giúp ít.

0 hữu ích 0 bình luận chia sẻ
0

Sử dụng mã này, bạn có thể nhận được thông báo ở chế độ nền / tiền cảnh và cũng có thể thực hiện hành động:

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

Trong ứng dụng sử dụng mã này:

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
      String key1Data = remoteMessage.getData().get("key1");
      // use key1Data to according to your need
    }
0 hữu ích 1 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ android firebase firebase-cloud-messaging , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading