Skip to content

Commit

Permalink
Merge pull request #360 from olucurious/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
olucurious authored Sep 13, 2024
2 parents 3a4aa8c + 3e79b05 commit fb637ce
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,7 @@ Unreleased
- Replace deprecated urllib3.Retry options v2

.. _Łukasz Rogowski: https://github.com/Rogalek

- Explicitly handle 403 SENDER_ID_MISMATCH response

.. _James Priebe: https://github.com/J-Priebe/
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,18 @@ proxy_dict = {
}
fcm = FCMNotification(service_account_file="<service-account-json-path>", project_id="<project-id>", proxy_dict=proxy_dict)

# OR using credentials from environment variable
# Often you would save service account json in evironment variable
# Assuming GCP_CREDENTIALS contains the data (TIP: use "export GCP_CREDENTIALS=$(filename.json)" to quickly load the json)

from google.oauth2 import service_account
gcp_json_credentials_dict = json.loads(os.getenv('GCP_CREDENTIALS', None))
credentials = service_account.Credentials.from_service_account_info(gcp_json_credentials_dict, scopes=['https://www.googleapis.com/auth/firebase.messaging'])
fcm = FCMNotification(service_account_file=None, credentials=credentials, project_id="<project-id>")

# Your service account file can be gotten from: https://console.firebase.google.com/u/0/project/_/settings/serviceaccounts/adminsdk

# Now you are ready to send notification
fcm_token = "<fcm token>"
notification_title = "Uber update"
notification_body = "Hi John, your order is on the way!"
Expand Down Expand Up @@ -106,6 +116,15 @@ result = fcm.notify(fcm_token=fcm_token, notification_body=notification_body, da
# To a single device
result = fcm.notify(fcm_token=fcm_token, data_payload=data_payload)

# Only string key and values are accepted. booleans, nested dicts are not supported
# To send nested dict, use something like
data_payload = {
"foo": "bar",
"data": json.dumps(data).
}
# For more info on format see https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#Message
# and https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json

# Use notification messages when you want FCM to handle displaying a notification on your app's behalf.
# Use data messages when you just want to process the messages only in your app.
# PyFCM can send a message including both notification and data payloads.
Expand Down
2 changes: 1 addition & 1 deletion pyfcm/__meta__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
__summary__ = "Python client for FCM - Firebase Cloud Messaging (Android, iOS and Web)"
__url__ = "https://github.com/olucurious/pyfcm"

__version__ = "2.0.6"
__version__ = "2.0.7"

__author__ = "Emmanuel Adegbite"
__email__ = "olucurious@gmail.com"
Expand Down
9 changes: 8 additions & 1 deletion pyfcm/baseapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
AuthenticationError,
InvalidDataError,
FCMError,
FCMSenderIdMismatchError,
FCMServerError,
FCMNotRegisteredError,
)
Expand Down Expand Up @@ -185,12 +186,14 @@ def parse_response(self, response):
Parses the json response sent back by the server and tries to get out the important return variables
Returns:
dict: name (str) - uThe identifier of the message sent, in the format of projects/*/messages/{message_id}
dict: name (str) - The identifier of the message sent, in the format of projects/*/messages/{message_id}
Raises:
FCMServerError: FCM is temporary not available
AuthenticationError: error authenticating the sender account
InvalidDataError: data passed to FCM was incorrecly structured
FCMSenderIdMismatchError: the authenticated sender is different from the sender registered to the token
FCMNotRegisteredError: device token is missing, not registered, or invalid
"""

if response.status_code == 200:
Expand All @@ -210,6 +213,10 @@ def parse_response(self, response):
)
elif response.status_code == 400:
raise InvalidDataError(response.text)
elif response.status_code == 403:
raise FCMSenderIdMismatchError(
"The authenticated sender ID is different from the sender ID for the registration token."
)
elif response.status_code == 404:
raise FCMNotRegisteredError("Token not registered")
else:
Expand Down
9 changes: 9 additions & 0 deletions pyfcm/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ class FCMNotRegisteredError(FCMError):
pass


class FCMSenderIdMismatchError(FCMError):
"""
Sender is not allowed for the given device tokens
https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode
"""

pass


class FCMServerError(FCMError):
"""
Internal server error or timeout error on Firebase cloud messaging server
Expand Down
11 changes: 6 additions & 5 deletions pyfcm/fcm.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ def notify(
timeout (int, optional): Set time limit for the request
Returns:
dict: Response from FCM server (`multicast_id`, `success`, `failure`, `canonical_ids`, `results`)
dict: name (str) - The identifier of the message sent, in the format of projects/*/messages/{message_id}
Raises:
AuthenticationError: If api_key is not set or provided or there is an error authenticating the sender.
FCMServerError: Internal server error or timeout error on Firebase cloud messaging server
InvalidDataError: Invalid data provided
InternalPackageError: Mostly from changes in the response of FCM, contact the project owner to resolve the issue
FCMServerError: FCM is temporary not available
AuthenticationError: error authenticating the sender account
InvalidDataError: data passed to FCM was incorrecly structured
FCMSenderIdMismatchError: the authenticated sender is different from the sender registered to the token
FCMNotRegisteredError: device token is missing, not registered, or invalid
"""
payload = self.parse_payload(
fcm_token=fcm_token,
Expand Down

0 comments on commit fb637ce

Please sign in to comment.