symfonyoauth-2.0firebase-cloud-messaginggoogle-oauthsymfony6

Firebase - Notification push - Oauth2 - 401 invalid authentication credentials - Symfony


I'm currently trying to create a micro service to push notification to devices. I'm using Firebase messaging and now we need to use their last API. It use Oauth2, i tried with Postman to make a push and it worked flawlessly. But, when I tried to implement it in Symfony, I had problem with credentials. It seems that the token generate by google/auth doesn't work. Especially because with Postman, that token begin by "ya29" even refreshed.

I hope, you will be able to help. Thank you.

I installed "google/auth". I have a config.json file to use with Oauth.

{
  "type": "service_account",
  "project_id": "my project",
  "private_key_id": "my private key id",
  "private_key": "my private key",
  "client_email": "firebase-adminsdk-*****@***********.iam.gserviceaccount.com",
  "client_id": "my client id",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-g050t%40***********.iam.gserviceaccount.com",
  "universe_domain": "googleapis.com"
}

My service

namespace App\Service\Firebase;

use App\Service\AbstractApiClient;
use Exception;
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Auth\HttpHandler\HttpHandlerFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

class MessagingService extends AbstractApiClient
{
    /**
     * @throws TransportExceptionInterface
     * @throws Exception
     */
    public function send(string $project, array $body): ResponseInterface
    {
        $credential = new ServiceAccountCredentials(
            'https://googleapis.com/auth/firebase.messaging',
            json_decode(file_get_contents('../config/firebase/' . $project . '/config.json'), true)
        );

//        $token = $credential->fetchAuthToken(HttpHandlerFactory::build());
        $token = $credential->fetchAuthToken();

        $firebaseUrl = 'https://fcm.googleapis.com/v1/projects/' . $project . '/messages:send';

        return $this->request(
            Request::METHOD_POST,
            $firebaseUrl,
            [
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Authorization' => 'Bearer ' . $token['id_token']
                ],
                'body' => $body
            ]
        );
    }
}


Solution

  • I finally succeed !

    For those who need it, I used googleapis/google-api-php-client

    public function send(string $project, array $notification): ResponseInterface
    {
        $client = new Client();
    
        $client->setAuthConfig('../config/firebase/' . $project . '/config.json');
        $client->addScope(Google_Service_FirebaseCloudMessaging::CLOUD_PLATFORM);
        $client->fetchAccessTokenWithAssertion();
        $accessToken = $client->getAccessToken();
        $token = $accessToken['access_token'];
    
        $firebaseUrl = 'https://fcm.googleapis.com/v1/projects/' . $project . '/messages:send';
    
        return $this->request(
            Request::METHOD_POST,
            $firebaseUrl,
            [
                'headers' => [
                    'Content-Type' => 'application/json',
                    'Authorization' => 'Bearer ' . $token
                ],
                'json' => $notification
            ]
        );
    }
    

    Have fun ! :D