IIT-BHU-InstiApp / lite-hai-backend

https://lite-hai.copsiitbhu.co.in/
13 stars 20 forks source link

Notifications for workshops #35

Closed nishantkr18 closed 3 years ago

shivanshs9 commented 4 years ago

@nishantwrp @krashish8 here's the Django model you'll need to store FCM tokens

from firebase_admin import exceptions, messaging
from google.auth.exceptions import TransportError

class Device(models.Model):
    DEVICE_ANDROID = 'and'
    DEVICE_IPHONE = 'ios'

    DEVICE_CHOICE = (
        (DEVICE_ANDROID, 'Android'),
        (DEVICE_IPHONE, 'iOS')
    )

    device_type = models.CharField(choices=DEVICE_CHOICE, max_length=3)
    device_token = models.CharField(max_length=256)
    auth_token = models.OneToOneField(
        AuthToken, on_delete=models.CASCADE,
        primary_key=True, related_name='device')
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, verbose_name='User',
        related_name='devices', related_query_name='device',
        on_delete=models.CASCADE)

    objects = DeviceManager()

    class Meta:
        unique_together = ('device_type', 'user')

    def __str__(self):
        return f'{self.user} in {self.device_type}'

    def notify(self, data, body=None, title=None):
        msg_notification = messaging.Notification(title, body)
        msg = messaging.Message(
            data=data, token=self.device_token,
            notification=msg_notification
        )

        try:
            messaging.send(msg)
        except (exceptions.FirebaseError, TransportError) as e:
            logger.warn('Could not send notification!')
            logger.error(e)

    def send_message(self, message):
        if not self.device_token:
            # logger.error(f'{self.user} does not have an active device!')
            return
        message.token = self.device_token

        try:
            messaging.send(message)
        except (exceptions.FirebaseError, TransportError) as e:
            logger.error(msg=f'Could not send message! Cause: {e}')
shivanshs9 commented 4 years ago

Create a new endpoint for user to update their own device token:

def get_device_type(ua):
    """
    Parses HTTP User-Agent header string to return the device type.

    Arguments:
            ua {str} -- The User-Agent header value from HTTP request

    Returns:
            One of the following:
            and
            ios
            web
    """
    ua = ua.lower()
    # TODO: Write the logic to get device type from HTTP User Agent (like below)
    if 'android' in ua:
        return Device.DEVICE_ANDROID

class DeviceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Device
        fields = ('device_type', 'device_token')
        read_only_fields = ('device_type', )

class DetailDevice(generics.RetrieveUpdateAPIView):
    """
    Update the Device token linked with given AuthToken
    """
    serializer_class = DeviceSerializer
    permission_classes = (IsAuthenticated, )

    def get_object(self):
        user = self.request.user
        device_type = get_device_type(self.request.META.get('HTTP_USER_AGENT', 'web'))
        return get_object_or_404(Device, user=user, device_type=device_type)