From 920f922445af59728c95d731a30572ca37792e93 Mon Sep 17 00:00:00 2001 From: Johannes Schriewer Date: Wed, 28 Jul 2021 18:18:50 +0200 Subject: [PATCH 1/2] Bugfix: Fix spurious migration updates when `FCM_USE_SESSION_USER` changes --- README.md | 2 +- .../migrations/0001_initial.py | 80 +++++++++++-------- firebase_notification/models.py | 33 +++++++- 3 files changed, 78 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 38f2a85..54c97c1 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ celery worker --app=yourproject.celery ## Required Settings - `FCM_API_KEY`: API key for fcm service -- `FCM_USE_SESSION_USER`: If `True` require the connection of a device registration to a django user +- `FCM_USE_SESSION_USER`: If `True` require the connection of a device registration to a django user, if `False` the `FCMDevice` class will have no user field. ## Python API diff --git a/firebase_notification/migrations/0001_initial.py b/firebase_notification/migrations/0001_initial.py index 1ca6006..cd8ee1f 100644 --- a/firebase_notification/migrations/0001_initial.py +++ b/firebase_notification/migrations/0001_initial.py @@ -1,33 +1,47 @@ -# Generated by Django 3.0.8 on 2021-01-14 17:34 - -from django.conf import settings -import django.contrib.postgres.fields.jsonb -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='FCMDevice', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('registration_id', models.CharField(max_length=255, unique=True)), - ('registration_target', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)), - ('is_active', models.BooleanField(default=True, help_text='Inactive devices will not be sent notifications')), - ('platform', models.CharField(blank=True, choices=[('ANDROID', 'Android'), ('IOS', 'iOS'), ('CHROME', 'Web')], max_length=7, null=True)), - ('connect_date', models.DateField(blank=True, null=True)), - ('app_version', models.CharField(blank=True, max_length=255, null=True)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - ] +# Generated by Django 3.2.5 on 2021-07-28 16:02 + +from django.conf import settings +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='FCMDeviceWithoutUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('registration_id', models.CharField(max_length=255, unique=True)), + ('registration_target', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)), + ('is_active', models.BooleanField(default=True, help_text='Inactive devices will not be sent notifications')), + ('platform', models.CharField(blank=True, choices=[('ANDROID', 'Android'), ('IOS', 'iOS'), ('CHROME', 'Web')], max_length=7, null=True)), + ('connect_date', models.DateField(blank=True, null=True)), + ('app_version', models.CharField(blank=True, max_length=255, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='FCMDeviceWithUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('registration_id', models.CharField(max_length=255, unique=True)), + ('registration_target', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)), + ('is_active', models.BooleanField(default=True, help_text='Inactive devices will not be sent notifications')), + ('platform', models.CharField(blank=True, choices=[('ANDROID', 'Android'), ('IOS', 'iOS'), ('CHROME', 'Web')], max_length=7, null=True)), + ('connect_date', models.DateField(blank=True, null=True)), + ('app_version', models.CharField(blank=True, max_length=255, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/firebase_notification/models.py b/firebase_notification/models.py index d116813..e810a12 100644 --- a/firebase_notification/models.py +++ b/firebase_notification/models.py @@ -5,7 +5,7 @@ from django.conf import settings -class FCMDevice(models.Model): +class FCMDeviceWithUser(models.Model): FCM_PLATFORMS = ( ('ANDROID', 'Android'), ('IOS', 'iOS'), @@ -16,8 +16,8 @@ class FCMDevice(models.Model): user = models.ForeignKey( get_user_model(), on_delete=models.CASCADE, - null=not settings.FCM_USE_SESSION_USER, - blank=not settings.FCM_USE_SESSION_USER + null=False, + blank=False ) registration_target = JSONField(blank=True, default=dict) is_active = models.BooleanField(default=True, help_text=_("Inactive devices will not be sent notifications")) @@ -30,3 +30,30 @@ class FCMDevice(models.Model): def __str__(self): return 'Registration <{}> for device on {}'.format(str(self.registration_target), self.platform) + + +class FCMDeviceWithoutUser(models.Model): + FCM_PLATFORMS = ( + ('ANDROID', 'Android'), + ('IOS', 'iOS'), + ('CHROME', 'Web'), + ) + + registration_id = models.CharField(unique=True, max_length=255) + registration_target = JSONField(blank=True, default=dict) + is_active = models.BooleanField(default=True, help_text=_("Inactive devices will not be sent notifications")) + platform = models.CharField(choices=FCM_PLATFORMS, max_length=7, null=True, blank=True) + connect_date = models.DateField(null=True, blank=True) + app_version = models.CharField(max_length=255, null=True, blank=True) + + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return 'Registration <{}> for device on {}'.format(str(self.registration_target), self.platform) + + +if settings.FCM_USE_SESSION_USER: + FCMDevice = FCMDeviceWithUser +else: + FCMDevice = FCMDeviceWithoutUser \ No newline at end of file From b2f499e0a0fef628ced95474a97e63f624f650bc Mon Sep 17 00:00:00 2001 From: Johannes Schriewer Date: Wed, 28 Jul 2021 18:26:53 +0200 Subject: [PATCH 2/2] Bugfix: Switch out Admin registration to correct model --- firebase_notification/admin.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/firebase_notification/admin.py b/firebase_notification/admin.py index 401c126..b74bc5b 100644 --- a/firebase_notification/admin.py +++ b/firebase_notification/admin.py @@ -1,14 +1,23 @@ from django.contrib import admin +from django.conf import settings from .models import FCMDevice - # Register your models here. -@admin.register(FCMDevice) -class FCMDeviceAdmin(admin.ModelAdmin): - search_fields = ('user', 'registration_target') - list_filter = ('user', 'platform', 'is_active', 'app_version') - list_display = ('user', 'platform', 'is_active', 'app_version', 'created_at', 'updated_at', 'registration_id') - list_display_links = ('registration_id',) - readonly_fields = ('created_at', 'updated_at') +if settings.FCM_USE_SESSION_USER: + @admin.register(FCMDevice) + class FCMDeviceAdmin(admin.ModelAdmin): + search_fields = ('user', 'registration_target') + list_filter = ('user', 'platform', 'is_active', 'app_version') + list_display = ('user', 'platform', 'is_active', 'app_version', 'created_at', 'updated_at', 'registration_id') + list_display_links = ('registration_id',) + readonly_fields = ('created_at', 'updated_at') +else: + @admin.register(FCMDevice) + class FCMDeviceAdmin(admin.ModelAdmin): + search_fields = ('registration_target', ) + list_filter = ('platform', 'is_active', 'app_version') + list_display = ('platform', 'is_active', 'app_version', 'created_at', 'updated_at', 'registration_id') + list_display_links = ('registration_id',) + readonly_fields = ('created_at', 'updated_at')