Задать вопрос
@bagrovykt

Почему fcm-django: send_message при использовании UUID юзера валит ошибку?

Django 5.2.8, DRF 3.16.1, FCM-Django 2.3.1

Стандартная модель User была расширена и id переопределен в uuid.
При сохранении экземпляра соседней модели должен отправляться webpush для группы пользователей, но в консоли ошибка:
Exception in thread Thread-1:
Traceback (most recent call last):
File ".......Lib\threading.py", line 1075, in _bootstrap_inner
self.run()
File ".......Lib\threading.py", line 1012, in run
self._target(*self._args, **self._kwargs)
TypeError: 'FirebaseResponseDict' object is not callable


Тем не менее webpush успешно доставляются, но как будто FirebaseResponseDict возвращается в виде объекта вместо словаря. Пока id был int, ошибка не проявлялась.

models.py:

class ApiUser(AbstractUser):
    ...
    id = models.UUIDField(max_length=64, primary_key=True, default=uuid.uuid4, editable=False, unique=True)
    ...

# В соседней модели при вызове метода save() отправляем webPush
    def save(self, *args, **kwargs):
        webPushThread = threading.Thread(
            target=FCMDevice.objects.all().filter(user__role__gte=2)
            .send_message(
                Message(notification=Notification(title="title", body="body" image=""))
            )
        )
        webPushThread.start()
  • Вопрос задан
  • 71 просмотр
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Нетология
    Django: создание backend-приложений
    7 недель
    Далее
  • Академия Eduson
    Python-разработчик
    9 месяцев
    Далее
  • Skillbox
    Python-фреймворк Django
    3 месяца
    Далее
Решения вопроса 1
@bagrovykt Автор вопроса
Вопрос решен. Вместо это неказистой конструкции
webPushThread = threading.Thread(
            target=FCMDevice.objects.all().filter(user__role__gte=2)
            .send_message(
                Message(notification=Notification(title="title", body="body" image=""))
            )
        )

написал вот такую обертку
class webPushThread(threading.Thread):
    def __init__(self, role, title, body, image="https://reactiv.su/images/logo-square.png"):
        self.role = role
        self.title = title
        self.body = body
        self.image = image
        super().__init__()

    def run(self):
        devices = FCMDevice.objects.filter(user__role__gte=self.role, active=True)
        devices.send_message(
            Message(
                notification=Notification(title=self.title, body=self.body,
                                          image=self.image))
        )

Ну и в методе save()
webPushThread(role, title, body, image).start()
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Everything_is_bad
Учимся пользоваться threading и заодно читать доки, а не прибегать сразу сюда, почему ты в target засунул результат выполнения, зачем тут тогда потоки, ты понимаешь как это работает?
Правильно https://docs.python.org/3/library/threading.html#i... в target ссылку на исполняемый объект, а в args и kwargs параметры с которыми этот объект нужно выполнить. Ну и допом, делать это в save, так себе идея, как и threading в django. Так же не нужно ставить тег DRF, у тебя в вопросе ничего про него нет.

Тем не менее webpush успешно доставляются
Конечно доставляются, ты доставку выполнил вне потока

но как будто FirebaseResponseDict возвращается в виде объекта вместо словаря. Пока id был int, ошибка не проявлялась.
ты что-то путаешь, если в target подставить словарь, ты получишь ту же самую ошибки. Скорее всего код был совсем другим.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы