# async-firebase is a lightweight asynchronous client to interact with Firebase Cloud Messaging for sending push notification to Android and iOS devices
[![PyPI download month](https://img.shields.io/pypi/dm/async-firebase.svg)](https://pypi.python.org/pypi/async-firebase/)
[![PyPI version fury.io](https://badge.fury.io/py/async-firebase.svg)](https://pypi.python.org/pypi/async-firebase/)
[![PyPI license](https://img.shields.io/pypi/l/async-firebase.svg)](https://pypi.python.org/pypi/async-firebase/)
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/async-firebase.svg)](https://pypi.python.org/pypi/async-firebase/)
[![CI](https://github.com/healthjoy/async-firebase/actions/workflows/ci.yml/badge.svg)](https://github.com/healthjoy/async-firebase/actions/workflows/ci.yml)
[![Codacy coverage](https://img.shields.io/codacy/coverage/b6a59cdf5ca64eab9104928d4f9bbb97?logo=codacy)](https://app.codacy.com/gh/healthjoy/async-firebase/dashboard)
* Free software: MIT license
* Requires: Python 3.8+
## Features
* Extremely lightweight and does not rely on ``firebase-admin`` which is hefty
* Send push notifications to Android and iOS devices
* Send Multicast push notification to Android and iOS devices
* Send Web push notifications
* Set TTL (time to live) for notifications
* Set priority for notifications
* Set collapse-key for notifications
* Dry-run mode for testing purpose
* Topic Management
## Installation
To install `async-firebase`, simply execute the following command in a terminal:
```shell script
$ pip install async-firebase
```
## Getting started
### async-firebase < 3.0.0
To send push notification to Android:
```python3
import asyncio
from async_firebase import AsyncFirebaseClient
async def main():
client = AsyncFirebaseClient()
client.creds_from_service_account_file("secret-store/mobile-app-79225efac4bb.json")
# or using dictionary object
# client.creds_from_service_account_info({...}})
device_token = "..."
android_config = client.build_android_config(
priority="high",
ttl=2419200,
collapse_key="push",
data={"discount": "15%", "key_1": "value_1", "timestamp": "2021-02-24T12:00:15"},
title="Store Changes",
body="Recent store changes",
)
response = await client.push(device_token=device_token, android=android_config)
print(response.success, response.message_id)
if __name__ == "__main__":
asyncio.run(main())
```
To send push notification to iOS:
```python3
import asyncio
from async_firebase import AsyncFirebaseClient
async def main():
client = AsyncFirebaseClient()
client.creds_from_service_account_file("secret-store/mobile-app-79225efac4bb.json")
# or using dictionary object
# client.creds_from_service_account_info({...}})
device_token = "..."
apns_config = client.build_apns_config(
priority="normal",
ttl=2419200,
apns_topic="store-updated",
collapse_key="push",
title="Store Changes",
alert="Recent store changes",
badge=1,
category="test-category",
custom_data={"discount": "15%", "key_1": "value_1", "timestamp": "2021-02-24T12:00:15"}
)
response = await client.push(device_token=device_token, apns=apns_config)
print(response.success)
if __name__ == "__main__":
asyncio.run(main())
```
This prints:
```shell script
"projects/mobile-app/messages/0:2367799010922733%7606eb557606ebff"
```
To manual construct message:
```python3
import asyncio
from datetime import datetime
from async_firebase.messages import APNSConfig, APNSPayload, ApsAlert, Aps
from async_firebase import AsyncFirebaseClient
async def main():
apns_config = APNSConfig(**{
"headers": {
"apns-expiration": str(int(datetime.utcnow().timestamp()) + 7200),
"apns-priority": "10",
"apns-topic": "test-topic",
"apns-collapse-id": "something",
},
"payload": APNSPayload(**{
"aps": Aps(**{
"alert": ApsAlert(title="some-title", body="alert-message"),
"badge": 0,
"sound": "default",
"content_available": True,
"category": "some-category",
"mutable_content": False,
"custom_data": {
"link": "https://link-to-somewhere.com",
"ticket_id": "YXZ-655512",
},
})
})
})
device_token = "..."
client = AsyncFirebaseClient()
client.creds_from_service_account_info({...})
response = await client.push(device_token=device_token, apns=apns_config)
print(response.success)
if __name__ == "__main__":
asyncio.run(main())
```
### async-firebase >= 3.0.0
To send push notification to Android:
```python3
import asyncio
from async_firebase import AsyncFirebaseClient
from async_firebase.messages import Message
async def main():
client = AsyncFirebaseClient()
client.creds_from_service_account_file("secret-store/mobile-app-79225efac4bb.json")
# or using dictionary object
# client.creds_from_service_account_info({...}})
device_token: str = "..."
android_config = client.build_android_config(
priority="high",
ttl=2419200,
collapse_key="push",
data={"discount": "15%", "key_1": "value_1", "timestamp": "2021-02-24T12:00:15"},
title="Store Changes",
body="Recent store changes",
)
message = Message(android=android_config, token=device_token)
response = await client.send(message)
print(response.success, response.message_id)
if __name__ == "__main__":
asyncio.run(main())
```
To send push notification to iOS:
```python3
import asyncio
from async_firebase import AsyncFirebaseClient
from async_firebase.messages import Message
async def main():
client = AsyncFirebaseClient()
client.creds_from_service_account_file("secret-store/mobile-app-79225efac4bb.json")
# or using dictionary object
# client.creds_from_service_account_info({...}})
device_token: str = "..."
apns_config = client.build_apns_config(
priority="normal",
ttl=2419200,
apns_topic="store-updated",
collapse_key="push",
title="Store Changes",
alert="Recent store changes",
badge=1,
category="test-category",
custom_data={"discount": "15%", "key_1": "value_1", "timestamp": "2021-02-24T12:00:15"}
)
message = Message(apns=apns_config, token=device_token)
response = await client.send(message)
print(response.success)
if __name__ == "__main__":
asyncio.run(main())
```
This prints:
```shell script
"projects/mobile-app/messages/0:2367799010922733%7606eb557606ebff"
```
To manual construct message:
```python3
import asyncio
from datetime import datetime
from async_firebase.messages import APNSConfig, APNSPayload, ApsAlert, Aps, Message
from async_firebase import AsyncFirebaseClient
async def main():
apns_config = APNSConfig(**{
"headers": {
"apns-expiration": str(int(datetime.utcnow().timestamp()) + 7200),
"apns-priority": "10",
"apns-topic": "test-topic",
"apns-collapse-id": "something",
},
"payload": APNSPayload(**{
"aps": Aps(**{
"alert": ApsAlert(title="some-title", body="alert-message"),
"badge": 0,
"sound": "default",
"content_available": True,
"category": "some-category",
"mutable_content": False,
"custom_data": {
"link": "https://link-to-somewhere.com",
"ticket_id": "YXZ-655512",
},
})
})
})
device_token: str = "..."
client = AsyncFirebaseClient()
client.creds_from_service_account_info({...})
message = Message(apns=apns_config, token=device_token)
response = await client.send(message)
print(response.success)
if __name__ == "__main__":
asyncio.run(main())
```
### Topic Management
You can subscribe and unsubscribe client app instances in bulk approach by passing a list of registration tokens to the subscription method to subscribe the corresponding devices to a topic:
```python3
import asyncio
from async_firebase import AsyncFirebaseClient
async def main():
device_tokens: list[str] = ["...", "..."]
client = AsyncFirebaseClient()
client.creds_from_service_account_info({...})
response = await client.subscribe_devices_to_topic(
device_tokens=device_tokens, topic_name="some-topic"
)
print(response)
if __name__ == "__main__":
asyncio.run(main())
```
To unsubscribe devices from a topic by passing registration tokens to the appropriate method:
```python3
import asyncio
from async_firebase import AsyncFirebaseClient
async def main():
device_tokens: list[str] = ["...", "..."]
client = AsyncFirebaseClient()
client.creds_from_service_account_info({...})
response = await client.unsubscribe_devices_from_topic(
device_tokens=device_tokens, topic_name="some-topic"
)
print(response)
if __name__ == "__main__":
asyncio.run(main())
```
## License
``async-firebase`` is offered under the MIT license.
## Source code
The latest developer version is available in a GitHub repository:
[https://github.com/healthjoy/async-firebase](https://github.com/healthjoy/async-firebase)
Raw data
{
"_id": null,
"home_page": "https://github.com/healthjoy/async-firebase",
"name": "async-firebase",
"maintainer": "Healthjoy Developers",
"docs_url": null,
"requires_python": "<3.13,>=3.8",
"maintainer_email": "developers@healthjoy.com",
"keywords": "async, asyncio, firebase, fcm, python3, push-notifications",
"author": "Oleksandr Omyshev",
"author_email": "oomyshev@healthjoy.com",
"download_url": "https://files.pythonhosted.org/packages/cc/69/cafcd00fddcc117082cfdc4c47cc8f593e10c624c8ccc00de1fb6304d069/async_firebase-3.9.0.tar.gz",
"platform": null,
"description": "# async-firebase is a lightweight asynchronous client to interact with Firebase Cloud Messaging for sending push notification to Android and iOS devices\n\n[![PyPI download month](https://img.shields.io/pypi/dm/async-firebase.svg)](https://pypi.python.org/pypi/async-firebase/)\n[![PyPI version fury.io](https://badge.fury.io/py/async-firebase.svg)](https://pypi.python.org/pypi/async-firebase/)\n[![PyPI license](https://img.shields.io/pypi/l/async-firebase.svg)](https://pypi.python.org/pypi/async-firebase/)\n[![PyPI pyversions](https://img.shields.io/pypi/pyversions/async-firebase.svg)](https://pypi.python.org/pypi/async-firebase/)\n[![CI](https://github.com/healthjoy/async-firebase/actions/workflows/ci.yml/badge.svg)](https://github.com/healthjoy/async-firebase/actions/workflows/ci.yml)\n[![Codacy coverage](https://img.shields.io/codacy/coverage/b6a59cdf5ca64eab9104928d4f9bbb97?logo=codacy)](https://app.codacy.com/gh/healthjoy/async-firebase/dashboard)\n\n\n * Free software: MIT license\n * Requires: Python 3.8+\n\n## Features\n\n * Extremely lightweight and does not rely on ``firebase-admin`` which is hefty\n * Send push notifications to Android and iOS devices\n * Send Multicast push notification to Android and iOS devices\n * Send Web push notifications\n * Set TTL (time to live) for notifications\n * Set priority for notifications\n * Set collapse-key for notifications\n * Dry-run mode for testing purpose\n * Topic Management\n\n## Installation\nTo install `async-firebase`, simply execute the following command in a terminal:\n```shell script\n$ pip install async-firebase\n```\n\n## Getting started\n### async-firebase < 3.0.0\nTo send push notification to Android:\n```python3\nimport asyncio\n\nfrom async_firebase import AsyncFirebaseClient\n\n\nasync def main():\n client = AsyncFirebaseClient()\n client.creds_from_service_account_file(\"secret-store/mobile-app-79225efac4bb.json\")\n\n # or using dictionary object\n # client.creds_from_service_account_info({...}})\n\n device_token = \"...\"\n\n android_config = client.build_android_config(\n priority=\"high\",\n ttl=2419200,\n collapse_key=\"push\",\n data={\"discount\": \"15%\", \"key_1\": \"value_1\", \"timestamp\": \"2021-02-24T12:00:15\"},\n title=\"Store Changes\",\n body=\"Recent store changes\",\n )\n response = await client.push(device_token=device_token, android=android_config)\n\n print(response.success, response.message_id)\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\nTo send push notification to iOS:\n\n```python3\nimport asyncio\n\nfrom async_firebase import AsyncFirebaseClient\n\n\nasync def main():\n client = AsyncFirebaseClient()\n client.creds_from_service_account_file(\"secret-store/mobile-app-79225efac4bb.json\")\n\n # or using dictionary object\n # client.creds_from_service_account_info({...}})\n\n device_token = \"...\"\n\n apns_config = client.build_apns_config(\n priority=\"normal\",\n ttl=2419200,\n apns_topic=\"store-updated\",\n collapse_key=\"push\",\n title=\"Store Changes\",\n alert=\"Recent store changes\",\n badge=1,\n category=\"test-category\",\n custom_data={\"discount\": \"15%\", \"key_1\": \"value_1\", \"timestamp\": \"2021-02-24T12:00:15\"}\n )\n response = await client.push(device_token=device_token, apns=apns_config)\n\n print(response.success)\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\nThis prints:\n\n```shell script\n\"projects/mobile-app/messages/0:2367799010922733%7606eb557606ebff\"\n```\n\nTo manual construct message:\n```python3\nimport asyncio\nfrom datetime import datetime\n\nfrom async_firebase.messages import APNSConfig, APNSPayload, ApsAlert, Aps\nfrom async_firebase import AsyncFirebaseClient\n\n\nasync def main():\n apns_config = APNSConfig(**{\n \"headers\": {\n \"apns-expiration\": str(int(datetime.utcnow().timestamp()) + 7200),\n \"apns-priority\": \"10\",\n \"apns-topic\": \"test-topic\",\n \"apns-collapse-id\": \"something\",\n },\n \"payload\": APNSPayload(**{\n \"aps\": Aps(**{\n \"alert\": ApsAlert(title=\"some-title\", body=\"alert-message\"),\n \"badge\": 0,\n \"sound\": \"default\",\n \"content_available\": True,\n \"category\": \"some-category\",\n \"mutable_content\": False,\n \"custom_data\": {\n \"link\": \"https://link-to-somewhere.com\",\n \"ticket_id\": \"YXZ-655512\",\n },\n })\n })\n })\n\n device_token = \"...\"\n\n client = AsyncFirebaseClient()\n client.creds_from_service_account_info({...})\n response = await client.push(device_token=device_token, apns=apns_config)\n print(response.success)\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n### async-firebase >= 3.0.0\nTo send push notification to Android:\n```python3\nimport asyncio\n\nfrom async_firebase import AsyncFirebaseClient\nfrom async_firebase.messages import Message\n\n\nasync def main():\n client = AsyncFirebaseClient()\n client.creds_from_service_account_file(\"secret-store/mobile-app-79225efac4bb.json\")\n\n # or using dictionary object\n # client.creds_from_service_account_info({...}})\n\n device_token: str = \"...\"\n\n android_config = client.build_android_config(\n priority=\"high\",\n ttl=2419200,\n collapse_key=\"push\",\n data={\"discount\": \"15%\", \"key_1\": \"value_1\", \"timestamp\": \"2021-02-24T12:00:15\"},\n title=\"Store Changes\",\n body=\"Recent store changes\",\n )\n message = Message(android=android_config, token=device_token)\n response = await client.send(message)\n\n print(response.success, response.message_id)\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\nTo send push notification to iOS:\n\n```python3\nimport asyncio\n\nfrom async_firebase import AsyncFirebaseClient\nfrom async_firebase.messages import Message\n\n\nasync def main():\n client = AsyncFirebaseClient()\n client.creds_from_service_account_file(\"secret-store/mobile-app-79225efac4bb.json\")\n\n # or using dictionary object\n # client.creds_from_service_account_info({...}})\n\n device_token: str = \"...\"\n\n apns_config = client.build_apns_config(\n priority=\"normal\",\n ttl=2419200,\n apns_topic=\"store-updated\",\n collapse_key=\"push\",\n title=\"Store Changes\",\n alert=\"Recent store changes\",\n badge=1,\n category=\"test-category\",\n custom_data={\"discount\": \"15%\", \"key_1\": \"value_1\", \"timestamp\": \"2021-02-24T12:00:15\"}\n )\n message = Message(apns=apns_config, token=device_token)\n response = await client.send(message)\n\n print(response.success)\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\nThis prints:\n\n```shell script\n\"projects/mobile-app/messages/0:2367799010922733%7606eb557606ebff\"\n```\n\nTo manual construct message:\n```python3\nimport asyncio\nfrom datetime import datetime\n\nfrom async_firebase.messages import APNSConfig, APNSPayload, ApsAlert, Aps, Message\nfrom async_firebase import AsyncFirebaseClient\n\n\nasync def main():\n apns_config = APNSConfig(**{\n \"headers\": {\n \"apns-expiration\": str(int(datetime.utcnow().timestamp()) + 7200),\n \"apns-priority\": \"10\",\n \"apns-topic\": \"test-topic\",\n \"apns-collapse-id\": \"something\",\n },\n \"payload\": APNSPayload(**{\n \"aps\": Aps(**{\n \"alert\": ApsAlert(title=\"some-title\", body=\"alert-message\"),\n \"badge\": 0,\n \"sound\": \"default\",\n \"content_available\": True,\n \"category\": \"some-category\",\n \"mutable_content\": False,\n \"custom_data\": {\n \"link\": \"https://link-to-somewhere.com\",\n \"ticket_id\": \"YXZ-655512\",\n },\n })\n })\n })\n\n device_token: str = \"...\"\n\n client = AsyncFirebaseClient()\n client.creds_from_service_account_info({...})\n message = Message(apns=apns_config, token=device_token)\n response = await client.send(message)\n print(response.success)\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n### Topic Management\nYou can subscribe and unsubscribe client app instances in bulk approach by passing a list of registration tokens to the subscription method to subscribe the corresponding devices to a topic:\n```python3\nimport asyncio\n\nfrom async_firebase import AsyncFirebaseClient\n\n\nasync def main():\n device_tokens: list[str] = [\"...\", \"...\"]\n\n client = AsyncFirebaseClient()\n client.creds_from_service_account_info({...})\n response = await client.subscribe_devices_to_topic(\n device_tokens=device_tokens, topic_name=\"some-topic\"\n )\n print(response)\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\nTo unsubscribe devices from a topic by passing registration tokens to the appropriate method:\n```python3\nimport asyncio\n\nfrom async_firebase import AsyncFirebaseClient\n\n\nasync def main():\n device_tokens: list[str] = [\"...\", \"...\"]\n\n client = AsyncFirebaseClient()\n client.creds_from_service_account_info({...})\n response = await client.unsubscribe_devices_from_topic(\n device_tokens=device_tokens, topic_name=\"some-topic\"\n )\n print(response)\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n## License\n\n``async-firebase`` is offered under the MIT license.\n\n## Source code\n\nThe latest developer version is available in a GitHub repository:\n[https://github.com/healthjoy/async-firebase](https://github.com/healthjoy/async-firebase)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Async Firebase Client - a Python asyncio client to interact with Firebase Cloud Messaging in an easy way.",
"version": "3.9.0",
"project_urls": {
"Homepage": "https://github.com/healthjoy/async-firebase",
"Repository": "https://github.com/healthjoy/async-firebase"
},
"split_keywords": [
"async",
" asyncio",
" firebase",
" fcm",
" python3",
" push-notifications"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "73e1dafb4a1eb0a278dec5efeaee4408a42580ca2ffbdac1feb3483177fe09f9",
"md5": "ca1d9c13c651146b208aeb270b44e925",
"sha256": "f12be915aeec52360b761e2518770e7b9b7feaa5c0e3cffc24374d8067554ae5"
},
"downloads": -1,
"filename": "async_firebase-3.9.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ca1d9c13c651146b208aeb270b44e925",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<3.13,>=3.8",
"size": 26554,
"upload_time": "2024-10-30T14:33:10",
"upload_time_iso_8601": "2024-10-30T14:33:10.740213Z",
"url": "https://files.pythonhosted.org/packages/73/e1/dafb4a1eb0a278dec5efeaee4408a42580ca2ffbdac1feb3483177fe09f9/async_firebase-3.9.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "cc69cafcd00fddcc117082cfdc4c47cc8f593e10c624c8ccc00de1fb6304d069",
"md5": "c17789de0b5536894f0cc25bea2894de",
"sha256": "c8443cc367f90966c03b1936fa3fb3a37f0f2a307342ac9b43e071d6d375d77c"
},
"downloads": -1,
"filename": "async_firebase-3.9.0.tar.gz",
"has_sig": false,
"md5_digest": "c17789de0b5536894f0cc25bea2894de",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.13,>=3.8",
"size": 24581,
"upload_time": "2024-10-30T14:33:12",
"upload_time_iso_8601": "2024-10-30T14:33:12.582353Z",
"url": "https://files.pythonhosted.org/packages/cc/69/cafcd00fddcc117082cfdc4c47cc8f593e10c624c8ccc00de1fb6304d069/async_firebase-3.9.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-30 14:33:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "healthjoy",
"github_project": "async-firebase",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "async-firebase"
}