Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FCM notifications and collapse_key

I'm sending notifications to users Android devices though the Firebase Notification console and I notice that even if I send 10 different notifications while the user device is offline, once the user goes online she/he will receive all 10.

However in Firebase documentation it is stated that:

FCM allows a maximum of four different collapse keys per device to be used by the app server at any given time. In other words, the FCM connection server can simultaneously store four different collapsible send-to-sync messages per device, each with a different collapse key. If you exceed this number, FCM only keeps four collapse keys, with no guarantees about which ones are kept.

So shouldn't the user receive only 4 notifications? Am I missing something? (I am not extending the FirebaseMessagingService, I leave the notification handling to the SDK)

UPDATE: If you don't specify a collapse key in the Firebase notifications console, it seems that an implicit collapse key is assigned to the notification and that is the package name of the app. I've tested that by checking all key/value pairs of the getIntent().getExtras() key set, once I launch the app by tapping on the notification. And indeed, I am getting a collapse_key key with the value of the package name, even if I haven't specified one.

UPDATE 2: I tried to handle the notifications by extending the FirebaseMessagingService, so that I receive the messages from the notifications console, when the app is in the foreground. I receive the notification message and I manually display a notification to the user. And guess what. Collapse keys work great! I receive a single notification even if I send multiple notifications with the same collapse key. BUT this happens obviously only when the app is in the foreground, because the Firebase SDK doesn't call the onMessageReceived() when the app is in the background, but instead it handles the notification itself. Does that mean that this is a bug of the Firebase SDK? (since the issue happens only when the notification is shown by the SDK)

So question remains, why do I receive all 10 notifications since each notification has the same collapse key? Maybe an FCM bug?

like image 201
steliosf Avatar asked Jun 14 '17 18:06

steliosf


People also ask

What is FCM Collapse_key?

FCM allows a maximum of four different collapse keys per device to be used by the app server at any given time. In other words, the FCM connection server can simultaneously store four different collapsible send-to-sync messages per device, each with a different collapse key.

What are FCM notifications?

Firebase Cloud Messaging (FCM), formerly called Google Cloud Messaging (GCM), is a free cloud service from Google that allows app developers to send notifications and messages to users across a variety of platforms, including Android, iOS and web applications.

What is difference between APNs and FCM?

APNs needs to be used for push messaging when an application is in the background. Hence, FCM uses APNs to deliver messages when the message contains user visible payload, e.g., body, sound etc. FCM also delivers via APNs when content available is set.

Does FCM uses Websockets?

FCM (Firebase Cloud Messaging) uses HTTP and XMPP Server Protocol serving JSON and Plain Text both.


1 Answers

After reading the post and comments, I'm not completely clear on everything that has been tried, which efforts were successful and which failed. I'll cover a number if items and hope something is helpful.

Your post indicates that for some tests, you specified a collapse key when you composed the message in Firebase console. That is not possible. If you opened Advanced options and entered a key/value pair under Custom data, that will not work. Those values are stored in the message under the data key, not at the top level of the message where collapse_key must appear. Also, Table 1 in the documentation includes a warning that data keys should not be any of the reserved words in the table, specifically citing collapse_key:

The key should not be a reserved word ("from" or any word starting with "google" or "gcm"). Do not use any of the words defined in this table (such as collapse_key).

As noted in the comments to your post, the console automatically assigns a collapse key that is the package name, so user entry of a collapse key is not needed.

That said, my experiences with the console match yours. I create messages by entering only Message text and the device token. I see no collapse processing; each message is received by the device. Based on my experience with the tests described below, this seems to be a problem with the console and not with collapse processing in general. This is odd, because if I send the messages when the app is in the foreground, and onMessageReceived() is invoked, I have debug logging that outputs the collapse key in the message using getCollapseKey(). That output confirms that the key is present and is my app package name.

You indicate that you did some tests sending notifications from a cloud function. I did my own testing with this cloud function and observed the expected message collapse:

exports.test = functions.database.ref('/test').onWrite(event => {
  const token = 'dK1FjGbNr6k:APA91bH7Vz3x...icGO56sJ7rAqOXRI';

  console.log('Sending notification...');

  const payload = {
    notification: {
      title: 'Message',
      body: 'Just one please!'
    }
  };

  const options = {
    collapseKey: 'green'
  };

  return admin.messaging().sendToDevice(token, payload, options).then(response => {
    console.log('Done');
  });
});

I also sent this message using browser app Advanced Rest Client, and also saw correct message collapsing:

{
  "to": "dK1FjGbNr6k:APA91bH7Vz3x...O56sJ7rAqOXRI",
  "collapse_key": "green",
  "notification": {
    "title": "Message",
    "body": "Just one please!"
  }
}

I'll also share that Firebase emits an analytics log message when a notification message is received. This is useful for testing, when you want to get a count of messages received:

D/FA: Logging event (FE): notification_receive(_nr), Bundle[{firebase_event_origin(_o)=fcm, message_device_time(_ndt)=0, message_time(_nmt)=1498227476, message_id(_nmid)=6447126672094369335}]
like image 99
Bob Snyder Avatar answered Sep 20 '22 20:09

Bob Snyder