FCM Django

3.2.0 · active · verified Fri Apr 17

fcm-django provides a convenient way to integrate Firebase Cloud Messaging (FCM) into Django applications, allowing developers to send push notifications to mobile devices and web browsers. It simplifies device registration and message dispatching. The current version is 3.2.0, and the library maintains an active development cycle with frequent releases addressing new features and compatibility updates.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to configure `fcm-django` settings, register a device, and send a push notification. It includes a self-contained Django settings configuration for easy execution. Remember to replace placeholder credentials and device tokens with your actual Firebase project details and a valid client-side FCM token for successful testing.

import os
from django.conf import settings
from fcm_django.models import FCMDevice
from firebase_admin.messaging import Message, Notification

# --- Configure Django settings (this would typically be in your settings.py) ---
# For a runnable example, we configure it on the fly.
# Replace with your actual Firebase project credentials or use environment variables.
# Set environment variables for actual testing, e.g., in your shell:
# export FCM_PROJECT_ID="your-firebase-project-id"
# export FCM_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
# export FCM_CLIENT_EMAIL="firebase-adminsdk@your-project-id.iam.gserviceaccount.com"
# export FCM_TEST_DEVICE_TOKEN="your_actual_device_token_from_client_app"

if not settings.configured:
    settings.configure(
        INSTALLED_APPS=[
            'django.contrib.auth', # Required for user foreign key in FCMDevice
            'django.contrib.contenttypes',
            'fcm_django'
        ],
        DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
        DEBUG=True,
        SECRET_KEY='a-very-secret-key-for-example', # Placeholder for runnable example
        FCM_DJANGO_SETTINGS={
            "FIREBASE_ADMIN_CREDENTIALS": {
                "type": "service_account",
                "project_id": os.environ.get("FCM_PROJECT_ID", "your-firebase-project-id"),
                "private_key_id": os.environ.get("FCM_PRIVATE_KEY_ID", "your-private-key-id"),
                "private_key": os.environ.get("FCM_PRIVATE_KEY", "-----BEGIN PRIVATE KEY-----\nPLACE_YOUR_PRIVATE_KEY_HERE\n-----END PRIVATE KEY-----\n").replace("\\n", "\n"),
                "client_email": os.environ.get("FCM_CLIENT_EMAIL", "firebase-adminsdk@your-project-id.iam.gserviceaccount.com"),
                "client_id": os.environ.get("FCM_CLIENT_ID", "12345678901234567890"),
                "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%40your-project-id.iam.gserviceaccount.com"
            }
            # Alternatively, specify a path to your service account JSON file:
            # "FIREBASE_ADMIN_CREDENTIALS_FILE": os.environ.get("FCM_CREDENTIALS_PATH", None)
        }
    )

    # Initialize Django apps system and create tables for fcm_django model
    import django
    django.setup()
    from django.db import connection
    with connection.schema_editor() as schema_editor:
        try:
            schema_editor.create_model(FCMDevice)
        except Exception as e:
            # Ignore if table already exists, common in re-runs of snippet
            if 'already exists' not in str(e):
                raise

# --- Your application logic (e.g., in a view, management command, or script) ---

# This token would come from your client-side Firebase SDK.
# Replace with a real FCM device token for actual testing.
device_token = os.environ.get("FCM_TEST_DEVICE_TOKEN", "YOUR_FCM_DEVICE_TOKEN_HERE")
user = None # Link to a Django User model instance if available

if "YOUR_FCM_DEVICE_TOKEN_HERE" in device_token:
    print("Warning: Please replace 'YOUR_FCM_DEVICE_TOKEN_HERE' with an actual device token from your client-side app.")
    print("         Without a valid token, no notification will be sent.")

# Register or get an FCM device
device, created = FCMDevice.objects.get_or_create(
    registration_id=device_token,
    defaults={
        "name": "Test Device",
        "active": True,
        "type": "android" # or 'ios', 'web'
    }
)

if created:
    print(f"Registered new FCM device: {device.registration_id}")
else:
    print(f"FCM device already registered or updated: {device.registration_id}")

# Send a notification to the device
try:
    # Using FCMDeviceQuerySet.send_message for convenience and bulk support
    response = FCMDevice.objects.filter(id=device.id).send_message(
        title="Hello from FCM-Django!",
        body="This is a test push notification sent via FCM.",
        data={"custom_key": "custom_value"}, # Optional data payload
        sound="default" # Optional sound
    )
    print(f"Notification sent successfully: {response}")

except Exception as e:
    print(f"Error sending notification: {e}")
    if "InvalidRegistration" in str(e) or "NotFoundError" in str(e):
        print("This often means the device token is invalid or expired. Ensure 'YOUR_FCM_DEVICE_TOKEN_HERE' is current.")
    elif "default app has not been initialized" in str(e):
        print("Firebase Admin SDK not initialized. Check FCM_DJANGO_SETTINGS configuration.")

view raw JSON →