diff --git a/README.rst b/README.rst index 7e0d691e..be9ceba4 100644 --- a/README.rst +++ b/README.rst @@ -103,6 +103,7 @@ For WNS, you need both the ``WNS_PACKAGE_SECURITY_KEY`` and the ``WNS_SECRET_KEY - ``USER_MODEL``: Your user model of choice. Eg. ``myapp.User``. Defaults to ``settings.AUTH_USER_MODEL``. - ``UPDATE_ON_DUPLICATE_REG_ID``: Transform create of an existing Device (based on registration id) into a update. See below `Update of device with duplicate registration ID`_ for more details. - ``UNIQUE_REG_ID``: Forces the ``registration_id`` field on all device models to be unique. +- ``DEFAULT_CLOUD_MESSAGE_TYPE``: The default cloud message type to use when registering a FCM/GCM device. Defaults to ``"FCM"``. Can be set to ``"GCM"`` to use Google Cloud Messaging instead. **APNS settings** diff --git a/push_notifications/migrations/0010_alter_gcmdevice_cloud_message_type.py b/push_notifications/migrations/0010_alter_gcmdevice_cloud_message_type.py new file mode 100644 index 00000000..2aa3a61a --- /dev/null +++ b/push_notifications/migrations/0010_alter_gcmdevice_cloud_message_type.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.10 on 2024-04-12 16:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("push_notifications", "0009_alter_apnsdevice_device_id"), + ] + + operations = [ + migrations.AlterField( + model_name="gcmdevice", + name="cloud_message_type", + field=models.CharField( + choices=[ + ("FCM", "Firebase Cloud Message"), + ("GCM", "Google Cloud Message"), + ], + default="FCM", + help_text="You should choose FCM or GCM", + max_length=3, + verbose_name="Cloud Message Type", + ), + ), + ] diff --git a/push_notifications/models.py b/push_notifications/models.py index 33f44205..67e6ea8a 100644 --- a/push_notifications/models.py +++ b/push_notifications/models.py @@ -87,6 +87,10 @@ def send_message(self, message, **kwargs): return messaging.BatchResponse(responses) +def get_default_cloud_message_type() -> str: + return SETTINGS.get("DEFAULT_CLOUD_MESSAGE_TYPE", "FCM") + + class GCMDevice(Device): # device_id cannot be a reliable primary key as fragmentation between different devices # can make it turn out to be null and such: @@ -98,7 +102,7 @@ class GCMDevice(Device): registration_id = models.TextField(verbose_name=_("Registration ID"), unique=SETTINGS["UNIQUE_REG_ID"]) cloud_message_type = models.CharField( verbose_name=_("Cloud Message Type"), max_length=3, - choices=CLOUD_MESSAGE_TYPES, default="FCM", + choices=CLOUD_MESSAGE_TYPES, default=get_default_cloud_message_type(), help_text=_("You should choose FCM, GCM is deprecated") ) objects = GCMDeviceManager() diff --git a/tests/test_models.py b/tests/test_models.py index 6a9996a7..0bff8f92 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,6 +1,9 @@ +import importlib +import json from unittest import mock -from django.test import TestCase +from django.conf import settings +from django.test import TestCase, override_settings from django.utils import timezone from firebase_admin import messaging from firebase_admin.exceptions import InvalidArgumentError @@ -468,3 +471,29 @@ def test_can_save_wsn_device(self): self.assertIsNotNone(device.pk) self.assertIsNotNone(device.date_created) self.assertEqual(device.date_created.date(), timezone.now().date()) + + def test_gcm_is_default_cloud_message_type_when_not_specified_in_settings(self) -> None: + self._validate_device_cloud_message_type(expected_cloud_message_type="GCM") + + @override_settings() + def test_cloud_message_type_is_set_to_gcm(self) -> None: + settings.PUSH_NOTIFICATIONS_SETTINGS.update({ + "DEFAULT_CLOUD_MESSAGE_TYPE": "GCM", + }) + self._validate_device_cloud_message_type(expected_cloud_message_type="GCM") + + @override_settings() + def test_cloud_message_type_is_set_to_fcm(self) -> None: + settings.PUSH_NOTIFICATIONS_SETTINGS.update({ + "DEFAULT_CLOUD_MESSAGE_TYPE": "FCM", + }) + self._validate_device_cloud_message_type(expected_cloud_message_type="FCM") + + def _validate_device_cloud_message_type(self, expected_cloud_message_type: str) -> None: + # Reload the models so that cached model is evicted and + # field default value is re-read from settings + import push_notifications.models + importlib.reload(push_notifications.models) + from push_notifications.models import GCMDevice + field_object = GCMDevice._meta.get_field("cloud_message_type") + self.assertEqual(field_object.default, expected_cloud_message_type)