Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ single-line-if-stmt=no
no-space-check=trailing-comma,dict-separator

# Maximum number of lines in a module
max-module-lines=1000
max-module-lines=1200

# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
Expand Down
32 changes: 31 additions & 1 deletion firebase_admin/messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,16 @@ class WebpushConfig(object):
data: A dictionary of data fields (optional). All keys and values in the dictionary must be
strings. When specified, overrides any data fields set via ``Message.data``.
notification: A ``messaging.WebpushNotification`` to be included in the message (optional).
fcm_options: A ``messaging.WebpushFcmOptions`` (optional).

.. _Webpush Specification: https://tools.ietf.org/html/rfc8030#section-5
"""

def __init__(self, headers=None, data=None, notification=None):
def __init__(self, headers=None, data=None, notification=None, fcm_options=None):
self.headers = headers
self.data = data
self.notification = notification
self.fcm_options = fcm_options


class WebpushNotificationAction(object):
Expand Down Expand Up @@ -355,6 +357,18 @@ def __init__(self, title=None, body=None, icon=None, actions=None, badge=None, d
self.custom_data = custom_data


class WebpushFcmOptions(object):
"""Options for features provided by the FCM SDK for Web.

Args:
link: The link to open when the user clicks on the notification.
For all URL values, HTTPS is required.
"""

def __init__(self, link=None):
self.link = link


class APNSConfig(object):
"""APNS-specific options that can be included in a message.

Expand Down Expand Up @@ -622,6 +636,7 @@ def encode_webpush(cls, webpush):
'headers': _Validators.check_string_dict(
'WebpushConfig.headers', webpush.headers),
'notification': cls.encode_webpush_notification(webpush.notification),
'fcm_options': cls.encode_webpush_fcm_options(webpush.fcm_options)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The json key should be called fcmOptions. The REST API documentation mentions fcm_options by error and the FCM team is going to fix it.

}
return cls.remove_null_values(result)

Expand Down Expand Up @@ -672,6 +687,21 @@ def encode_webpush_notification(cls, notification):
result[key] = value
return cls.remove_null_values(result)

@classmethod
def encode_webpush_fcm_options(cls, fcm_options):
"""Encodes an WebpushFcmOptions instance into JSON."""
if fcm_options is None:
return None
if not isinstance(fcm_options, WebpushFcmOptions):
raise ValueError('WebpushConfig.fcm_options must be an instance of '
'WebFcmOptions class.')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebpushFcmOptions

result = {
'link': _Validators.check_string(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also check for https:// prefix.

'WebpushFcmOptions.link', fcm_options.link),
}
return cls.remove_null_values(result)


@classmethod
def encode_webpush_notification_actions(cls, actions):
"""Encodes a list of WebpushNotificationActions into JSON."""
Expand Down
23 changes: 23 additions & 0 deletions tests/test_messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,29 @@ def test_invalid_action_icon(self, data):
assert str(excinfo.value) == 'WebpushNotificationAction.icon must be a string.'


class TestWebpushFcmOptionsEncoder(object):

def _check_fcm_options(self, fcm_options):
with pytest.raises(ValueError) as excinfo:
check_encoding(messaging.Message(
topic='topic', webpush=messaging.WebpushConfig(fcm_options=fcm_options)))
return excinfo

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a test case to verify the happy path.

@pytest.mark.parametrize('data', NON_OBJECT_ARGS)
def test_invalid_webpush_fcm_options(self, data):
with pytest.raises(ValueError) as excinfo:
check_encoding(messaging.Message(
topic='topic', webpush=messaging.WebpushConfig(fcm_options=data)))
expected = 'WebpushConfig.fcm_options must be an instance of WebFcmOptions class.'
assert str(excinfo.value) == expected

@pytest.mark.parametrize('data', NON_STRING_ARGS)
def test_invalid_link(self, data):
notification = messaging.WebpushFcmOptions(link=data)
excinfo = self._check_fcm_options(notification)
assert str(excinfo.value) == 'WebpushFcmOptions.link must be a string.'


class TestAPNSConfigEncoder(object):

@pytest.mark.parametrize('data', NON_OBJECT_ARGS)
Expand Down