Search by

A lightweight PHP client for Firebase Cloud Messaging (FCM) HTTP v1 API.

Package info

github.com/emirustaoglu/fcm

pkg:composer/emirustaoglu/fcm

Statistics

Installs: 4

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.0.1 2026-09-30 07:32 UTC

This package is auto-updated.

Last update: 2026-09-30 07:37:16 UTC


README

Türkçe · English

Latest Version Monthly Downloads Total Downloads PHP Version License

A small and independent PHP client focused on the Firebase Cloud Messaging (FCM) HTTP v1 API.

This package does not use the full Firebase Admin SDK. It focuses only on the need to send FCM messages.

Features

  • FCM HTTP v1 API
  • OAuth 2.0 JWT authentication with Service Account JSON
  • Access token caching
  • Send messages to tokens
  • Send messages to topics
  • Send messages using conditions
  • Notification payload
  • Data payload
  • Android config
  • APNs config
  • validate_only support
  • HTTP error handling
  • No Firebase/Google SDK dependencies; only PHP + cURL + JSON + OpenSSL

Requirements

  • PHP 8.2+
  • ext-curl
  • ext-json
  • ext-openssl

Installation

composer require emirustaoglu/fcm

Firebase Setup

The FCM HTTP v1 API must be enabled and available in your Firebase project.

You can create a Service Account JSON file from:

Project Settings → Service Accounts

Never commit your Service Account JSON file to a public repository.

Recommended approach:

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"

This version also supports providing the file path directly.

Basic Usage

<?php

require __DIR__ . '/vendor/autoload.php';

use emirustaoglu\fcm\Fcm;

$fcm = Fcm::fromServiceAccount(
    __DIR__ . '/service-account.json'
);

$response = $fcm->sendToToken(
    token: 'FCM_DEVICE_TOKEN',
    title: 'Hello',
    body: 'You have a new notification.'
);

print_r($response);

For a successful HTTP v1 request, Firebase returns a response containing the message name:

[
    'name' => 'projects/demo-project/messages/0:123456789'
]

Sending Data

$response = $fcm->sendToToken(
    token: $deviceToken,
    title: 'Order',
    body: 'You have a new order.',
    data: [
        'type' => 'order',
        'order_id' => 12345,
    ]
);

FCM data payload values are sent as strings.

Sending webPush

$response = $fcm->sendToToken(
    token: $deviceToken,
    title: 'Order',
    body: 'You have a new order.',
    webPush: [
        'notification' => [
            'requireInteraction' => true,
            'icon' => 'https://img.shields.io/badge/php-%3E%3D8.1-777BB4.svg'
        ],
        'fcm_options' => [
            'link' => 'https://github.com/emirustaoglu'
        ]
    ]
);

Topic

$response = $fcm->sendToTopic(
    topic: 'news',
    title: 'New News',
    body: 'A new article has been published.'
);

Condition

$response = $fcm->sendToCondition(
    condition: "'news' in topics && 'tr' in topics",
    title: 'Announcement',
    body: 'A new announcement has been published.'
);

Message Builder

For more advanced payloads, you can use the Message class:

use emirustaoglu\fcm\Message;

$message = Message::create()
    ->token($deviceToken)
    ->notification(
        title: 'Order',
        body: 'Your order is being prepared.'
    )
    ->data([
        'type' => 'order',
        'order_id' => 12345,
    ]);

$response = $fcm->send($message);

Notification Image

$message = Message::create()
    ->token($deviceToken)
    ->notification(
        title: 'New Product',
        body: 'Discover our new product.',
        image: 'https://example.com/product.jpg'
    );

$response = $fcm->send($message);

Android Configuration

use emirustaoglu\fcm\AndroidConfig;
use emirustaoglu\fcm\Message;

$message = Message::create()
    ->token($deviceToken)
    ->notification('Title', 'Message')
    ->android(
        new AndroidConfig(
            priority: 'HIGH',
            ttl: '3600s',
            collapseKey: 'orders',
            channelId: 'orders'
        )
    );

$response = $fcm->send($message);

APNs

use emirustaoglu\fcm\ApnsConfig;
use emirustaoglu\fcm\Message;

$message = Message::create()
    ->token($deviceToken)
    ->notification('Title', 'Message')
    ->apns(
        new ApnsConfig(
            headers: [
                'apns-priority' => '10',
            ],
            payload: [
                'aps' => [
                    'sound' => 'default',
                ],
            ]
        )
    );

$response = $fcm->send($message);

Validation Only

To validate an FCM request without actually delivering the message:

$response = $fcm->send(
    $message,
    validateOnly: true
);

This uses the validate_only feature of the HTTP v1 API.

Errors

General package exception:

use emirustaoglu\fcm\Exceptions\FcmException;

Authentication exception:

use emirustaoglu\fcm\Exceptions\AuthenticationException;

FCM HTTP request exception:

use emirustaoglu\fcm\Exceptions\FcmRequestException;

try {
    $response = $fcm->sendToToken(
        $deviceToken,
        'Test',
        'Hello'
    );
} catch (FcmRequestException $e) {
    echo $e->getStatusCode();

    print_r($e->getResponse());
}

Testing

composer install
composer test

Syntax check:

composer test:syntax

Design

This package intentionally does not cover other Firebase services.

Scope:

FCM HTTP v1
   │
   ├── Authentication
   │   └── Service Account → OAuth 2.0 access token
   │
   └── Messaging
       ├── Token
       ├── Topic
       ├── Condition
       ├── Notification
       ├── Data
       ├── Android
       └── APNs

Out of scope:

  • Firebase Authentication
  • Firestore
  • Realtime Database
  • Firebase Storage
  • Firebase Analytics
  • Firebase Remote Config
  • Firebase App Check
  • Firebase Admin SDK

Security

Do not commit your Service Account private key file to a Git repository.

For example:

service-account.json

If a Service Account private key is compromised, an attacker may gain authorized access to the FCM API.

Store Service Account credentials in a secure location on your server.

License

MIT