Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FCM HTTP v1 API and Multicasting Messages in PHP

I received an email from Google where starting June 20, 2024 the legacy Firebase Cloud Messaging (FCM) APIs will be discontinued.

I currently have a server where a php Cron send Android push notifications, every minutes, using legacy api including multiple tokens in registration_ids field and I can send message to multiple clients with one curl post request.

There is no chance, at the moment, to use multicasting messages with new Api, so if I need to send in 1 minute a message to 300 or 400 Android clients I need to call 300/400 times google server to post data? Did I get it right?

Whate are the best solution? thanks

like image 210
Cristian Avatar asked May 20 '26 21:05

Cristian


1 Answers

EDITED SOLUTION

I abandoned deprecated multicast messaging, I started using HTTP/2 and CURLPIPE_MULTIPLEX to send multiple requests across a single connection, each request targeting a different token. I tested it with 300 tokens and execution time was 3 seconds. My php code below:

function getAccessToken(){

    require "google-api-php-client/vendor/autoload.php";

    $client= new Google_Client();
    $client->setAuthConfig("firebasekey.json");
    $client->addScope('https://www.googleapis.com/auth/firebase.messaging');
    $client->refreshTokenWithAssertion();
    $token = $client->getAccessToken();
    $result=$token['access_token'];
            
    return $result;

}

function notification($notifications){
    
    $url = 'https://fcm.googleapis.com/v1/projects/your-project/messages:send';
    $headers = array(
        'Authorization: Bearer '.getAccessToken(),
        'Content-Type: application/json'
    );          

    $multiCurl = array();
    $mh = curl_multi_init();
    curl_multi_setopt($mh, CURLMOPT_PIPELINING,CURLPIPE_MULTIPLEX);

    foreach ($notifications as $i => $notification) {
        $multiCurl[$i] = curl_init();
        curl_setopt($multiCurl[$i], CURLOPT_URL,$url);
        curl_setopt($multiCurl[$i], CURLOPT_HTTPHEADER, $headers);
        curl_setopt($multiCurl[$i], CURLOPT_RETURNTRANSFER,true);
        curl_setopt($multiCurl[$i], CURLOPT_POST, true);
        curl_setopt($multiCurl[$i], CURLOPT_SSL_VERIFYHOST, 0);  
        curl_setopt($multiCurl[$i], CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($multiCurl[$i], CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_2_0);
        curl_setopt($multiCurl[$i], CURLOPT_POSTFIELDS, json_encode($notification,JSON_UNESCAPED_UNICODE));
        curl_multi_add_handle($mh, $multiCurl[$i]);
    }

    $index=null;
    do {
      curl_multi_exec($mh,$index);
      curl_multi_select($mh);
    } while($index > 0);
    
    foreach($multiCurl as $k => $ch) {
      $result[$k] = curl_multi_getcontent($ch);
      curl_multi_remove_handle($mh, $ch);
    }
    curl_multi_close($mh);
    
    print_r($result);
}


$mydata=array("messagefrom" => "server01","type" => "test");

//You need to create one notification for each token, you can put it inside a cycle and populate fields dynamically
$notifications[] = array(
    'message' => array(
        'token' => 'dNSYyeSETfa2LN2L39...',
        'android' => array(
            'priority' => 'high',
            'ttl' => '3600s',
        ),
        'data' => array(
            'mydata' => json_encode($mydata,JSON_UNESCAPED_UNICODE)         
        ),
    )
);

notification($notifications);

Google Api Client library https://github.com/googleapis/google-api-php-client/releases

To get the JSON with the key https://firebase.google.com/docs/admin/setup#initialize_the_sdk_in_non-google_environments

like image 157
Cristian Avatar answered May 22 '26 11:05

Cristian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!