46

I have a service that uses Firebase Cloud Messaging to communicate with its Android clients using FCM Data messages with the collapse_key parameter set. From the documentation about collapsable keys:

When there is a newer message that renders an older thread, related message becomes irrelevant to the client app and FCM replaces the older message. For example send-to-sync, or outdated notification messages.

This is what I'm looking for. I don't need all updates, only the last one is needed. But, I need it ASAP if the user is online.


However, I get a weird rate limiting that doesn't result in any HTTP error code. It is pretty easily reproducible just do 20 consecutive data messages and monitor the android FirebaseMessagingService.onMessageReceived:

for i in {1..20}; do 
  curl -v -X POST --header "Authorization: key=$SERVER_KEY" \
       --Header "Content-Type: application/json" \
       https://fcm.googleapis.com/fcm/send \
       -d "{\"to\":\"$CLIENT_TOKEN\", \
            \"data\":{\"counter\":\"$i\"}, \
            \"priority\":\"high\", \
            \"collapse_key\": \"test\" \
           }"
done

The bash script above is a bit hard to read, but I have a counter variable that I'm interested in.

After a few received messages (counter=~10) it stops and you need to toggle network status to get the last message with counter=20. The last message also appears after a few minutes (normally ~10 minutes) when a firebase check-in is requested (?).

Removing collapse_key from the curl command above results in that all 20 messages are received (where counter={1..20}).


So, the question: Is this a bug? Or am I shutting down (/rate limited) because I "abuse" the interface (since all requests sends back a 200 response I thought I was ok).

Sanchit
  • 315
  • 2
  • 20
dacwe
  • 43,066
  • 12
  • 116
  • 140
  • Note that I'm using "Data messages" and not "Notification messages" if that makes any difference. – dacwe Jan 08 '17 at 00:46
  • Both `priority` and `time_to_live` are specified outside the `notification` or `data` parameter, so there isn't really any difference whether which type of payload you're using (although each has [default values](https://firebase.google.com/docs/cloud-messaging/concept-options#setting-the-priority-of-a-message)). AFAIK, latency wise, it is best to simply set the `ttl` to `0`, but as you already know, the message will become a ***now or never*** type of message. But as per the behavior of FCM (even before for GCM), it will attempt to send the message asap, depending on the settings. – AL. Jan 09 '17 at 03:07
  • @AL. Seems like `collapse_key` gets rate limited see my edited question. – dacwe Jan 09 '17 at 17:16
  • If I understand that scenario you added in properly, adding the `collapse_key` to your payload treats your message as [collapsible](https://firebase.google.com/docs/cloud-messaging/concept-options#collapsible_and_non-collapsible_messages), wherein if the previous message with the same `collapse_key` is not yet sent to the device, it will be deleted and replaced with the most recent one with the same `collapse_key`. So the behavior you saw where not all the messages with `collapse_key` are received is just as expected. – AL. Jan 10 '17 at 02:19
  • @AL. I think this is a bug. I rewrote my question one last time. – dacwe Jan 10 '17 at 12:07
  • Is this happens every time? After receiving nearly about 10 messages it stops? – Pravin Divraniya Jan 11 '17 at 09:05
  • I think its a bug or might be network issue. – Pravin Divraniya Jan 11 '17 at 13:37
  • @PravinD yes, I would say around `10`. But to be on the safe side, change the loop counter above to `100`, and see where it stops receiving updates. I don't think it's a network issue. Same thing happens on wifi or mobile on the android clients side and from the servers point of view all requests gets a successful reply. – dacwe Jan 11 '17 at 19:57
  • There is a limit of 100 messages that can be stored without collapsing. 'If the limit is reached, all stored messages are discarded. When the device is back online, it receives a special message indicating that the limit was reached. The app can then handle the situation properly, typically by requesting a full sync from the app server.' This might be the case? – Pravin Divraniya Jan 12 '17 at 06:51
  • @PravinD that applies only to non-collapsable messages right? I'm already using collapsable messages. – dacwe Jan 12 '17 at 08:52
  • Yes you are right. – Pravin Divraniya Jan 12 '17 at 09:02
  • It seems to me a bug and suggesting you to post it . https://firebase.google.com/support/ – Pravin Divraniya Jan 12 '17 at 09:09

1 Answers1

1
<?php
#API access key from Google API's Console
    define( 'API_ACCESS_KEY', 'YOUR-SERVER-API-ACCESS-KEY-GOES-HERE' );
    $registrationIds = $_GET['id'];
#prep the bundle
     $msg = array
          (
        'body'  => 'Body  Of Notification',
        'title' => 'Title Of Notification',
                'icon'  => 'myicon',/*Default Icon*/
                'sound' => 'mySound'/*Default sound*/
          );
    $fields = array
            (
                'to'        => $registrationIds,
                'notification'  => $msg
            );


    $headers = array
            (
                'Authorization: key=' . API_ACCESS_KEY,
                'Content-Type: application/json'
            );
#Send Reponse To FireBase Server    
        $ch = curl_init();
        curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/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 Of FireBase Server
echo $result;

Put your data in body section.

PRATEEK BHARDWAJ
  • 2,364
  • 2
  • 21
  • 35