6

In order to use the HTTP V1 API (not the legacy API) with PHP, the REST interface has to be used.

https://firebase.google.com/docs/cloud-messaging/send-message#top_of_page

I am wondering how to get the Auth 2.0 access token?

https://firebase.google.com/docs/cloud-messaging/auth-server

As there is no Google API Client Library for PHP (see examples in the link above), how can the Auth 2.0 token be received with REST calls (no need to show PHP code)?

The related question: once received this short living token, how to refresh this token? What is the workflow?

Thanks a lot!

rds
  • 133
  • 1
  • 4
  • Check this answer: https://stackoverflow.com/a/61871906/3084577 – lubilis May 18 '20 at 14:32
  • This is the documentation about the REST call to get the OAuth Bearer token: https://developers.google.com/identity/protocols/oauth2/service-account#httprest – Peter Bruins Feb 17 '23 at 11:02

2 Answers2

5

If you want to get the access token manually, without external libraries, you can use this code. It creates a JWT token using your private key, and requests a bearer token.

function base64UrlEncode($text)
{
    return str_replace(
        ['+', '/', '='],
        ['-', '_', ''],
        base64_encode($text)
    );
}

// Read service account details
$authConfigString = file_get_contents("path_to_your_private_key_file_downloaded_from_firebase_console.json");

// Parse service account details
$authConfig = json_decode($authConfigString);

// Read private key from service account details
$secret = openssl_get_privatekey($authConfig->private_key);

// Create the token header
$header = json_encode([
    'typ' => 'JWT',
    'alg' => 'RS256'
]);

// Get seconds since 1 January 1970
$time = time();

$payload = json_encode([
    "iss" => $authConfig->client_email,
    "scope" => "https://www.googleapis.com/auth/firebase.messaging",
    "aud" => "https://oauth2.googleapis.com/token",
    "exp" => $time + 3600,
    "iat" => $time
]);

// Encode Header
$base64UrlHeader = base64UrlEncode($header);

// Encode Payload
$base64UrlPayload = base64UrlEncode($payload);

// Create Signature Hash
$result = openssl_sign($base64UrlHeader . "." . $base64UrlPayload, $signature, $secret, OPENSSL_ALGO_SHA256);

// Encode Signature to Base64Url String
$base64UrlSignature = base64UrlEncode($signature);

// Create JWT
$jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;

//-----Request token------
$options = array('http' => array(
    'method'  => 'POST',
    'content' => 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion='.$jwt,
    'header'  =>
        "Content-Type: application/x-www-form-urlencoded"
));
$context  = stream_context_create($options);
$responseText = file_get_contents("https://oauth2.googleapis.com/token", false, $context);

$response = json_decode($responseText);

The response has 3 fields: access_token, expires_in, and token_type.

You should store your token somewhere for future use, and request a new token when it expires, based on the expires_in. (After 1 hour).

You can also request tokens with a shorter lifetime, but the maximum lifetime of a token is 1 hour.

Peter Bruins
  • 807
  • 9
  • 25
4

There actually is a kind of "Google Api Client Library" for PHP, even two of them:

https://github.com/google/google-api-php-client

and

https://github.com/GoogleCloudPlatform/google-cloud-php

The one provides access to APIs that the other doesn't, so it's worth looking which one provides what - you will perhaps need to use both of them.

In the README of the https://github.com/google/google-api-php-client repository, you can find a description on how to obtain the OAuth access and refresh tokens.

Both libraries work with Guzzle underneath and provide a way to decorate your own Guzzle HTTP client with an authorization middleware so that you don't have to.

So, if one of the libraries doesn't provide support for an API you want to access, you can apply the code from the following snippet and access the API in question yourself (from Google Api PHP Client - "Making HTTP requests directly"):

// create the Google client
$client = new Google_Client();

/**
 * Set your method for authentication. Depending on the API, This could be
 * directly with an access token, API key, or (recommended) using
 * Application Default Credentials.
 */
$client->useApplicationDefaultCredentials();

// returns a Guzzle HTTP Client
$httpClient = $client->authorize();

Shameless plug: I am maintaining a separate Admin SDK for accessing Firebase related APIs at https://github.com/kreait/firebase-php , and it has a FCM component, which is documented here: https://firebase-php.readthedocs.io/en/stable/cloud-messaging.html

jeromegamez
  • 3,348
  • 1
  • 23
  • 36