Skip to main content

A Python library for receiving Firebase Cloud Messages

Project description

🔥 FCM Receiver

Powerful Python library for receiving Firebase Cloud Messages with end-to-end encryption support

Python Version License

OverviewInstallationQuick StartCallback ReferenceConfiguration


🚀 What is FCM Receiver?

FCM Receiver is a Python library that implements the low-level Firebase Cloud Messaging (FCM) protocol so you can receive push messages without depending on the official SDKs. It supports encrypted payloads, automatic reconnection, and credential persistence, making it a good fit for headless services or backend tooling.

✨ Key Highlights

  • 🔐 End-to-end encryption with elliptic curve keys
  • 📱 Connect to one or many Firebase projects simultaneously
  • 🔄 Automatic reconnect with exponential backoff
  • 💾 Credential storage helpers for repeatable startups
  • 🧩 Lightweight Python API without external Firebase dependencies

📦 Installation

Install from PyPI:

pip install fcm-receiver

Or install from source for local development:

git clone https://github.com/agusibrahim/pyfcm-receiver.git
cd pyfcm-receiver
pip install -e .

🎯 Quick Start

Basic Usage – Single Project

from fcm_receiver import FCMClient
import time

client = FCMClient()
client.project_id = "demo-project-123"
client.api_key = "demo-api-key"
client.app_id = "1:1234567890:web:demo-app"

# Every callback receives the data plus the client identifier.
def handle_data(payload: bytes, client_id: str) -> None:
    print(f"📨 [{client_id}]", payload.decode("utf-8"))

def handle_status(status: str, client_id: str) -> None:
    print(f"📡 [{client_id}] {status}")

client.on_data_message = handle_data
client.on_connection_status = handle_status

# Setup cryptographic keys and register the device with FCM.
client.create_new_keys()
client.register()

client.start_listening()

try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    client.close()

Basic Usage – Multiple Projects

from fcm_receiver import MultiFCMClient
import time

projects = [
    {
        "id": "marketing",
        "project_id": "demo-project-a",
        "api_key": "demo-api-key-a",
        "app_id": "1:100000000000:android:demoapp-a",
    },
    {
        "id": "logistics",
        "project_id": "demo-project-b",
        "api_key": "demo-api-key-b",
        "app_id": "1:200000000000:android:demoapp-b",
    },
]

multi = MultiFCMClient(projects=projects, credential_dir="./credentials")

def handle_notification(message: dict, client_id: str) -> None:
    title = message.get("payload", {}).get("title", "(no title)")
    print(f"🔔 [{client_id}] {title}")

def handle_data(data: bytes, client_id: str) -> None:
    print(f"📨 [{client_id}] {data.decode('utf-8')}")

def handle_status(status: str, client_id: str) -> None:
    print(f"📡 [{client_id}] {status}")

multi.on_notification_message = handle_notification
multi.on_data_message = handle_data
multi.on_connection_status = handle_status

print("🚀 Starting MultiFCMClient...")
multi.start()

try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    multi.close()

Note: Each project configuration must include a unique id. That identifier is returned as the second argument on every callback so you can distinguish which project emitted the event, even if multiple Firebase projects share the same project_id.


🔁 Callback Reference

The library sends an identifier alongside every callback so you always know which client produced the event.

FCMClient

  • on_notification_message(message: dict, client_id: str) – decrypted notification payloads
  • on_data_message(data: bytes, client_id: str) – raw decrypted bytes
  • on_raw_message(message_obj: object, client_id: str) – low-level protocol objects
  • on_connection_status(status: str, client_id: str) – lifecycle updates (connecting, connected, etc.)
  • on_tag(tag: int, name: str, client_id: str) – protocol tags emitted by the socket

MultiFCMClient

  • Accepts the same callbacks as FCMClient
  • Proxies events from all child clients while preserving the id you define in each project entry

⚙️ Configuration Notes

  • Every project dictionary passed to MultiFCMClient must include id, project_id, api_key, and app_id.
  • Credentials are cached under credential_dir so subsequent runs can reconnect quickly. Remove the files in that directory if you need to force a new registration.
  • Topic subscriptions are optional; call subscribe_to_topic() on the underlying FCMClient instances if needed.
  • Network access and valid Firebase credentials are still required at runtime even when using dummy values in these examples.

📄 License

This project is released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fcm_receiver-0.1.1.tar.gz (26.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fcm_receiver-0.1.1-py3-none-any.whl (26.3 kB view details)

Uploaded Python 3

File details

Details for the file fcm_receiver-0.1.1.tar.gz.

File metadata

  • Download URL: fcm_receiver-0.1.1.tar.gz
  • Upload date:
  • Size: 26.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for fcm_receiver-0.1.1.tar.gz
Algorithm Hash digest
SHA256 3061f046369926681368217d7abafec5db114108143c81f2407ac2db1df1d077
MD5 7c2e51a7dcbc36296b262ce3bd21c9b5
BLAKE2b-256 8da3f5f9446eef9621ab6522bf0d7cfe434ff1a63d2ab7b24d212c14a1daf2ca

See more details on using hashes here.

File details

Details for the file fcm_receiver-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: fcm_receiver-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 26.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for fcm_receiver-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 201de39d88d8cdf8ae129fd2c7825f0abb09ce4bd6b093d8f5183e28bbfdcae5
MD5 550aa6d46106307be1ed1d34bb39d31d
BLAKE2b-256 a5f07b9dc6ef99ff1292fe21ce9ce6b89cabc6dd277cd982a581f18ccc444540

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page