fcm-django Documentation

repository·master·Indexed 21 days ago

https://github.com/xtrinch/fcm-django

A Django application for sending push notifications to mobile devices and browsers using the Firebase Cloud Messaging (FCM) HTTP v1 API. It provides tools for sending single, bulk, and personalized messages, managing topic subscriptions, and integrating with Django REST Framework via FCMDeviceViewSet. The library supports custom FCMDevice models, MySQL compatibility settings, and integrates with the official firebase-admin package.

Tokens
12.2K
Snippets
44
Records
54
Agent score
72%

What's inside fcm-django

  1. Create Notification and Data messages

    master

    FCM messages generally fall into two categories: Notifications (which include a title, body, and image) and Data messages (which contain custom key-value pairs). You can also send both in a single message.

    from firebase_admin.messaging import Message, Notification
    
    # Notification message
    notification_msg = Message(
        notification=Notification(title="title", body="text", image="url"),
        topic="Optional topic parameter",
    )
    
    # Data message
    data_msg = Message(
        data={
            "Nick" : "Mario",
            "body" : "great match!",
            "Room" : "PortugalVSDenmark"
        },
        topic="Optional topic parameter",
    )
  2. Limitations and migration warnings for swapped FCMDevice models

    master

    The custom model functionality uses the swapper pattern (similar to Django's custom User model substitution). Users should be aware of the following:

    • Switching Models: It is difficult to start with the default model and switch to a swapped implementation later without complex migration hacking. It is recommended to decide on a custom model at the start of a project.
    • Existing Data: If you are implementing this on an existing project, you must manually move data from the original table to your new custom table.
    • Foreign Keys: If other tables in your database have Foreign Keys pointing to the default FCMDevice model, you must manually manage those relationships when moving to a swapped model.
  3. Handle duplicate registration IDs

    master
    When using the Django REST Framework (DRF) integration, any attempt to create a device with an existing registration_id will automatically be transformed into an update operation. This is useful for scenarios where a user logs out and another logs in on the same device, ensuring the device token is updated to the new user rather than creating a duplicate or leaving stale associations.
  4. Migrate from pyfcm to firebase-admin

    master

    Starting with version 1.0, fcm-django replaced the pyfcm package with Google's official firebase-admin package. This change removes the requirement for an API key and replaces it with service account credentials.

    To authenticate, you must provide a path to your Firebase service account JSON file using the GOOGLE_APPLICATION_CREDENTIALS environment variable.

    In your Django settings.py (or equivalent configuration file), you must initialize the Firebase app:

    from firebase_admin import initialize_app
    FIREBASE_APP = initialize_app()
    # Or simply:
    initialize_app()
  5. Integrate fcm-django with Django REST Framework (DRF)

    master

    You can expose device management via DRF using two types of ViewSets:

    1. FCMDeviceViewSet:

      • Uses standard DRF permissions.
      • Allows registering devices without an associated user.
      • Prevents duplicate registration_ids.
    2. FCMDeviceAuthorizedViewSet:

      • Uses IsAuthenticated and a custom IsOwner permission.
      • Requires authentication; all devices must be associated with a user.
      • Updates the existing device if a duplicate registration_id is provided.

    Routing Options

    Using Routers (Full API):

    from fcm_django.api.rest_framework import FCMDeviceAuthorizedViewSet
    from rest_framework.routers import DefaultRouter
    
    router = DefaultRouter()
    router.register('devices', FCMDeviceAuthorizedViewSet)
    
    urlpatterns = [
        path('', include(router.urls)),
    ]

    Using as_view (Granular Control):

    from fcm_django.api.rest_framework import FCMDeviceAuthorizedViewSet
    
    urlpatterns = [
        path('devices', FCMDeviceAuthorizedViewSet.as_view({'post': 'create'}), name='create_fcm_device'),
        path('devices/<str:registration_id>', FCMDeviceAuthorizedViewSet.as_view({'delete': 'destroy'}), name='delete_fcm_device'),
    ]
  6. Configure fcm-django in Django settings

    master

    To use fcm-django, add it to your INSTALLED_APPS and configure the FCM_DJANGO_SETTINGS dictionary. You must also ensure a Firebase app is initialized using firebase_admin.

    from firebase_admin import initialize_app
    
    INSTALLED_APPS = (
        ...
        "fcm_django"
        ...
    )
    
    # Initialize the Firebase app
    FIREBASE_APP = initialize_app()
    
    FCM_DJANGO_SETTINGS = {
         # An instance of firebase_admin.App to be used as default for all fcm-django requests
         # default: None (the default Firebase app)
        "DEFAULT_FIREBASE_APP": None,
         # default: _('FCM Django')
        "APP_VERBOSE_NAME": "[string for AppConfig's verbose_name]",
         # true if you want to have only one active device per registered user at a time
         # default: False
        "ONE_DEVICE_PER_USER": True,
         # devices to which notifications cannot be sent, are deleted upon receiving error response from FCM
         # default: False
        "DELETE_INACTIVE_DEVICES": True,
         # emit the ``device_deactivated`` signal when this library deactivates devices
         # default: False
        "EMIT_DEVICE_DEACTIVATED_SIGNAL": False,
    }
  7. Set a default Firebase app for all fcm-django requests

    master

    If you need to use a specific Firebase app (e.g., one initialized with custom credentials) for all fcm-django operations, assign that app instance to DEFAULT_FIREBASE_APP in your FCM_DJANGO_SETTINGS.

    # ... (credential setup code) ...
    
    # Initialize a second firebase app
    custom_credentials = CustomFirebaseCredentials(os.getenv('CUSTOM_GOOGLE_APPLICATION_CREDENTIALS'))
    FIREBASE_MESSAGING_APP = initialize_app(custom_credentials, name='messaging')
    
    FCM_DJANGO_SETTINGS = {
        "DEFAULT_FIREBASE_APP": FIREBASE_MESSAGING_APP,
    }
  8. Use a custom FCMDevice model

    master

    If you need to store additional information or change the field types of the default FCMDevice model, you can override it by inheriting from AbstractFCMDevice.

    To implement a custom model:

    1. Create a new model in your app inheriting from AbstractFCMDevice.
    2. Update your settings.py to point to your new model using the FCM_DJANGO_FCMDEVICE_MODEL setting.
    3. Run makemigrations and migrate for your app.

    Important Note on Database Tables: By default, both the package's original table and your custom table will exist in the database, but data will only appear in your custom table. To prevent the default fcm_django table from being created, remove "fcm_django" from INSTALLED_APPS in your settings.py (ensuring your own app remains in the list).

    # your_app/models.py
    import uuid
    from django.db import models
    from fcm_django.models import AbstractFCMDevice
    
    class CustomDevice(AbstractFCMDevice):
        # Overwriting existing fields
        id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
        # Adding new fields
        updated_at = models.DateTimeField(auto_now=True)
    
    # settings.py
    FCM_DJANGO_FCMDEVICE_MODEL = "your_app.CustomDevice"
  9. Configure Firebase Authentication

    master
    If you have already initialized a Firebase app, you can provide additional arguments like credentials, options, or name. A common method is to store an environment variable named GOOGLE_APPLICATION_CREDENTIALS which points to the path of your JSON credentials file.
  10. Register a custom FCMDevice model in Django Admin

    master

    If you have removed "fcm_django" from INSTALLED_APPS to use a swapped model, the device will not automatically appear in the Django admin panel. You must manually register your custom model using DeviceAdmin in your admin.py file.

    # your_app/admin.py
    from django.contrib import admin
    from fcm_django.admin import DeviceAdmin
    from your_app.models import CustomDevice
    
    # Register your custom model with the FCMDevice admin interface
    admin.site.register(CustomDevice, DeviceAdmin)
  11. Configure fcm-django settings

    master

    To use fcm-django, add it to your INSTALLED_APPS and configure the FCM_DJANGO_SETTINGS dictionary in your settings.py. You should also initialize a Firebase app using firebase_admin.

    from firebase_admin import initialize_app
    
    INSTALLED_APPS = (
        ...
        "fcm_django"
        ...
    )
    
    # Initialize your firebase app
    FIREBASE_APP = initialize_app()
    
    FCM_DJANGO_SETTINGS = {
         # An instance of firebase_admin.App to be used as default for all fcm-django requests
         # default: None (the default Firebase app)
        "DEFAULT_FIREBASE_APP": None,
         # default: _('FCM Django')
        "APP_VERBOSE_NAME": "[string for AppConfig's verbose_name]",
         # true if you want to have only one active device per registered user at a time
         # default: False
        "ONE_DEVICE_PER_USER": True,
         # devices to which notifications cannot be sent, are deleted upon receiving error response from FCM
         # default: False
        "DELETE_INACTIVE_DEVICES": False,
    }