Verified import paths — ran on the pinned version, not inferred.
FCMDevice
✓ from fcm_django.models import FCMDevice
✗ from fcm_django.models import FCMDevice
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.")