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
Overview • Installation • Quick Start • Callback Reference • Configuration
🚀 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 sameproject_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 payloadson_data_message(data: bytes, client_id: str)– raw decrypted byteson_raw_message(message_obj: object, client_id: str)– low-level protocol objectson_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
idyou define in each project entry
⚙️ Configuration Notes
- Every project dictionary passed to
MultiFCMClientmust includeid,project_id,api_key, andapp_id. - Credentials are cached under
credential_dirso 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 underlyingFCMClientinstances 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3061f046369926681368217d7abafec5db114108143c81f2407ac2db1df1d077
|
|
| MD5 |
7c2e51a7dcbc36296b262ce3bd21c9b5
|
|
| BLAKE2b-256 |
8da3f5f9446eef9621ab6522bf0d7cfe434ff1a63d2ab7b24d212c14a1daf2ca
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
201de39d88d8cdf8ae129fd2c7825f0abb09ce4bd6b093d8f5183e28bbfdcae5
|
|
| MD5 |
550aa6d46106307be1ed1d34bb39d31d
|
|
| BLAKE2b-256 |
a5f07b9dc6ef99ff1292fe21ce9ce6b89cabc6dd277cd982a581f18ccc444540
|