olucurious / pyfcm Goto Github PK
View Code? Open in Web Editor NEWPython client for FCM - Firebase Cloud Messaging (Android, iOS and Web)
Home Page: http://olucurious.github.io/PyFCM/
License: MIT License
Python client for FCM - Firebase Cloud Messaging (Android, iOS and Web)
Home Page: http://olucurious.github.io/PyFCM/
License: MIT License
I do not see any support for the content_available flag for sending gcm/fcm messages to ios devices
Since release of 1.1.0, the function notify_single_device is returning None for both success and failure when sending a push notification.
Maybe writing some unit tests for verifying response format would be advisable for next release (after bug fix)?
Did any of you try to send notification to 1000+ (e.g. 2450 tokens = 3 chunks) devices and more ?
From what I see method notify_multiple_devices splits that kind of request into chunks.
In reality it sends notification to only 1000 first registration tokens cause send_request method returns parsed response.
def send_request(self, payloads=None):
for payload in payloads:
response = requests.post(self.FCM_END_POINT, headers=self.request_headers(), data=payload)
if self.FCM_REQ_PROXIES:
response = requests.post(self.FCM_END_POINT, headers=self.request_headers(), data=payload, proxies=self.FCM_REQ_PROXIES)
if response.status_code == 200:
return self.parse_response(response)
elif response.status_code == 401:
raise AuthenticationError("There was an error authenticating the sender account")
elif response.status_code == 400:
raise InternalPackageError(response.text)
else:
raise FCMServerError("FCM server is temporarily unavailable")
in baseapi class, request is sent using request.send.
response = requests.post(self.FCM_END_POINT, headers=self.request_headers(), data=payload, verify=True)
so there's no way to config proxy but to modify the code in base class directly.
The full response looks like this:
{
"success":1,
"failure":2,
"failed_registration_ids":[
"regId1",
"regId2"
]
}
However the package is not passing failed_registration_ids in the result variable. If the user was to save devices somewhere and mark them as inactive, he would be inable to do so.
See https://github.com/olucurious/PyFCM/blob/master/pyfcm/baseapi.py#L51
File "/home/vagrant/files/localove/management/commands/send_test_notification.py", line 13, in handle
devices.send_message(data={"test": "test"}, badge=5)
File "/home/vagrant/files/fcm-django/fcm_django/models.py", line 52, in send_message
*_kwargs
File "/home/vagrant/files/fcm-django/fcm_django/fcm.py", line 51, in fcm_send_bulk_message
*_kwargs
File "/home/vagrant/env/lib/python3.4/site-packages/pyfcm/fcm.py", line 190, in notify_multiple_devices
return self.send_request([payload])
File "/home/vagrant/env/lib/python3.4/site-packages/pyfcm/baseapi.py", line 200, in send_request
raise InternalPackageError("Please create a new github issue describing what you're doing")
pyfcm.errors.InternalPackageError: Please create a new github issue describing what you're doing
Basically what I was trying to do is send bulk message to an empty queryset. I do believe there are use cases when there are simply no devices that match the query and I think it should not be left to the user to check if the queryset count is larger than zero.
Good day, it seems that the parser is accepting extra kwargs but it does not accept kwargs in notify_single_device
and notify_multiple_devices
. Thank you.
Here is the traceback. Deleting tornado.py fixes the problem.
Traceback (most recent call last):
File "/home/vmint/virtualenvs/chatserver/tests/PyFCM/pushNotificationTests.py", line 1, in
from pyfcm import FCMNotification
File "/home/vmint/virtualenvs/chatserver/tests/PyFCM/pyfcm/init.py", line 18, in
from .extensions.tornado import TornadoFCMNotification
File "/home/vmint/virtualenvs/chatserver/tests/PyFCM/pyfcm/extensions/tornado.py", line 28
return self.parse_response(response)
SyntaxError: 'return' with argument inside generator
Since notify_single_device() only parse one payload and attempt to send it to a single endpoint. There should be only one response from the FCM server.
For consistency, it would be better to return response instance rather a list wrapper containing only one element(on success). Trivial but can be easily added by overriding.
I am willing to provide patch if needed.
Thanks and good job.
๐
I try to import TornadoFCMNotification
in this way
from pyfcm import TornadoFCMNotification
but it fails with
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'TornadoFCMNotification'
after short investigation I realised that pip install pyfcm
don't install extensions
dir in lib/python3.5/site-packages/pyfcm/
.
Hi,
I used pyfcm in order to broadcast notification on android devices. in log following line display for every request :
Starting new HTTPS connection (1): fcm.googleapis.com
But in apple push notification, it uses sockets. it seems FCM support socket connection to make it live for bulk request.
Do you have any plane in order to support socket connection?
https://github.com/olucurious/PyFCM/blob/master/pyfcm/baseapi.py#L176
response = requests.post(self.FCM_END_POINT, headers=self.request_headers(), data=payload)
if self.FCM_REQ_PROXIES:
response = requests.post(self.FCM_END_POINT, headers=self.request_headers(), data=payload, proxies=self.FCM_REQ_PROXIES)
look here read the proxy too late.
so the error will appear first. if not using a proxy.
The API for FCM has parameter to send sound opction on mobile apps, but with pyFCM I could not found the option to send.
Hi,
I am using this module and it really seems to be very useful. Just need some information about the parameters which are passed while firing a new push notification.
In the push_service.notify_single_device and push_service.notify_multiple_devices there are some of these parameters which I need to use but not able to find any information on what to pass in these as values:
I am using cordova from the app side.
Even when not setting any notification contents, trying to push only a data notification, pyfcm inserts a "notification":{"icon":null}
stub, which appears to prevent service workers in browsers from receiving the notification.
Does not work (no notification received):
self.fcm.notify_multiple_devices(tokens, data_message=data, time_to_live=30)
Works (service worker receives notification):
payload = dict(
registration_ids=tokens,
data=data,
time_to_live=30,
priority='high',
)
self.fcm.send_request([json.dumps(payload)])
For now Firebase Cloud Messaging shows that api keys can be used, but not supported. We must use tokens for now. Is something changes in PyFCM?
But I don't want to include a message body, I just want to set the badge count. Use cases for this abound. Currently I've had to fork PyFCM and do like this:
from PyFCM.pyfcm import BaseAPI
import json
import config
base_service = BaseAPI(api_key=config.FCM_APIKey)
pushToken = "big-long-private-push-token-asdofiauusifaosdfuadfnua9sd8fnu9asd8f"
fcm_payload = dict()
fcm_payload['priority'] = 'high'
fcm_payload['notification'] = {}
fcm_payload['notification']['badge'] = 5
fcm_payload['to'] = pushToken
payload = (json.dumps(fcm_payload, separators=(',', ':'), sort_keys=True)
.encode('utf8'))
print base_service.send_request([payload])
I have seen this error recently. what's the problem?
hostname 'fcm.googleapis.com' doesn't match either of '*.com.com', 'com.com'
Hey,
Seems like the 1.2.0 tag and the repo do not reflect PIP 1.2.0 source. e.g. __version__
on the only commit.
PIP 1.2.0 package is also breaking my current builds because it had changed the return values on lines 283 and 87 in fcm.py
. I am expecting a list and I get a dict.
I guess this is not intentional.
Got this message when I tried to add the pyfcm in my INSTALLED_APPS
File "/home/<username>/.pyenv/versions/3.4.2/lib/python3.4/site-packages/pyfcm/fcm.py", line 1, in <module> from baseapi import BaseAPI ImportError: No module named 'baseapi'
ChunkedEncodingError: ('Connection broken: IncompleteRead(14 bytes read)', IncompleteRead(14 bytes read))
Hi there,
I'm playing with PyFCM to send message at localhost,
In my case, when I use curl, it takes <1sec to receive response.
But when y use PyFCM, it takes uncountable sec to receive response.
Any suggestion for me?
hello...
using this module can we send CALL notification to client on android and ios?
Thanks
Hi @olucurious ,
If I'm interpreting the code correctly, in do_request()
you check for Retry-After
header, and if it is present you resend the entire payload. However if the payload contains multiple registration ids, shouldn't we only resend the registration ids that the message has failed for? I may be misunderstanding what a payload is. I thought that deliveries to some registration ids could fail while others succeed, even if they are in the same request group.
E.g. the FCM API responds with 400 and a JSON body like {'error': 'MessageTooBig'}
results in the rather unclear exception pyfcm.errors.InternalPackageError: Please create a new github issue describing what you're doing
I receive this error when I try to build an app with the PyFCM v0.0.4
I fixed it by changing from baseapi import BaseAPI
in baseapi.py to
from .baseapi import BaseAPI
I've seen that on the tutorial you mention collapse_key as an optional argument, but i still don't know where does this argument goes on the syntaxis.
Thanks!
I am confused by the API, and it seems like the documentation does not match the behavior.
The documentation states that a single response will be returned, with counts of notifications in various states, and then an array of results in the same order as the registration ids in the request.
However, in practice, I see an both an outer array and an array in the results.
Reading the code, it seems like the library chunks into batches of 1000, and each outer array represents a chunk of 1000, and each inner array represents each ID in that chunk. It seems like since the library does chunking transparently to the user, that it should also transparently flatten the responses.
I have a problem when I try to send a notification with this code:
import database
from sqlalchemy.orm import Session
from pyfcm import FCMNotification
base = database.Base
engine = database.engine
session = Session(engine)
Client = base.classes.cliente
row = session.query(Client).filter(Client.id == 40).one()
last_fcm = row.last_fcm_id
key_file = open("d:\python34\eturn\key\eturn-df72e3592e73.json", "r")
key = key_file.read()
push_service = FCMNotification(api_key=key)
registration_id = last_fcm
message_title = "update"
data_message = {
"queue" : "1234",
"current" : "157",
"aat" : "300"
}
result = push_service.notify_single_device(registration_id=registration_id, message_title=message_title, data_message=data_message)
print(result)
This is the error:
Traceback (most recent call last):
File "D:/Python34/eturn/fcm_notifier.py", line 41, in
result = push_service.notify_single_device(registration_id=registration_id, message_title=message_title, data_message=data_message)
File "D:\Python34\eturn\lib\site-packages\pyfcm\fcm.py", line 84, in notify_single_device
return self.send_request([payload])
File "D:\Python34\eturn\lib\site-packages\pyfcm\baseapi.py", line 198, in send_request
raise FCMServerError("FCM server is temporarily unavailable")
pyfcm.errors.FCMServerError: FCM server is temporarily unavailable
Process finished with exit code 1
I'm working with pyfcm 1.0.0 and python 3.4
Checking the code from baseapi.py I found and modified this for know the real exception:
def send_request(self, payloads=None):
for payload in payloads:
response = requests.post(self.FCM_END_POINT, headers=self.request_headers(), data=payload)
if self.FCM_REQ_PROXIES:
response = requests.post(self.FCM_END_POINT, headers=self.request_headers(), data=payload, proxies=self.FCM_REQ_PROXIES)
if response.status_code == 200:
return self.parse_response(response)
elif response.status_code == 401:
raise AuthenticationError("There was an error authenticating the sender account")
elif response.status_code == 400:
raise InternalPackageError("Please create a new github issue describing what you're doing")
else:
print("Exception: ", response.status_code) # Line added
raise FCMServerError("FCM server is temporarily unavailable")
Then I get the exception 411.
This is:
411 - Length Required
I am doing something wrong?
Hi,
I tried to send a topic message with this configuration:
result = push_service.notify_topic_subscribers(topic_name="messages", message=message)
I get -
{'failure': 0, 'canonical_ids': 0, 'success': 1, 'multicast_id': None, 'results': []}
BUB .... NO MESSAGES FOUND ON FCM DB.
Please advise.
I have an android app that sends users registration_ids to the server but when users logout or reinstall the app the registration_id changed and I save a new registration id in my database . when I want to send a notification message I send message to all registration_ids of one user.
In sending process some responses show errors and they failed because of expired firebase registration id but how do I realize which registration id is invalid ?
notif_ids = notif_ids.objects.filter(user=user).all()
for notifid in notif_ids:
registration_id = notifid.firebase_id
message_title = "Test"
message_body = "Test"
try:
result = push_service.notify_single_device(registration_id=registration_id, message_title=message_title,
message_body=message_body, sound="Default", collapse_key="tag1")
# How Do I understand removed and invalid registration id from result ?!
except Exception as e:
pass
On including the key value "message_type" in the "data_message" parameter, the console reads success, but receiving device never gets the message.
changed from "message_type" to a couple of string variables, rather worked.
Hi,
I was using v1.0.6 previously and the response was a single dictionary when using notify_single_device().
Now with v1.1.2 and doing exactly the same, I get a list of a dictionary. Is this intended? I couldn't find any changelogs and the examples still seem to indicate that the output should be a dictionary, rather than a list of it.
Best
To send a message using body_loc_key
, body_loc_args
, title_loc_key
or title_loc_args
, the message_body
kwargs must be set to non-empty.
According to FCM docs, body
(message_body
) is optional. It was my understanding that body
and body_loc_key
+body_loc_args
are independent.
The condition check in question:
https://github.com/olucurious/PyFCM/blob/master/pyfcm/baseapi.py#L133
My current workaround to use body_loc_key
and body_loc_args
is
notify_multiple_devices(
registration_ids=[],
message_body=' ', // single space string
body_loc_key='mykey',
body_loc_args=['a', 'b', 'c'],
)
Hi,
does anyone have this problem or it is just me.
I receive notification, but not data messages.
data_message = {
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
push_service.notify_multiple_devices(registration_ids=registration_ids, data_message=data_message)
Android receives data message, but ios doesn't.
EDIT:
i got data message but with parameter content_available=True
in notify_multiple_devices
:
push_service.notify_multiple_devices(registration_ids=registration_ids, data_message=data_message, content_available=True)
Is this correct way?
Hi, I searched for something similar but I couldn't find.
I implemented the library on my server and successfully sent out a notification, it takes from 1 to 2 minutes to send a notification. Is this normal ? Sending a notification from Firebase console works instantly. There should be only a short delay.
Best regards,
Marian Pavel
I cannot send messages to all my devices. Any specific way I can achieve this without using the devices registration IDs. The same way I do it using the firebase console.
in the firebase console i can send a message to all users to a app
User Segment -> APP -> com.xxx.xxx
how can i do this with PyCM?
Ran into another problem. It looks like a lack for python3 support.
Changed xrange
at baseapi.py:69
to simply range
to fix it.
Not sure what are the implications of this, but it works :)
Running pip install pyfcm
installs version 0.0.4
when the latest on PyPI is 0.0.9
. Running pip install pyfcm==0.0.9
fails with:
$ pip install pyfcm==0.0.9
Collecting pyfcm==0.0.9
Could not find a version that satisfies the requirement pyfcm==0.0.9 (from versions: 0.0.1, 0.0.2, 0.0.4)
No matching distribution found for pyfcm==0.0.9
I believe this is because 0.0.4
is the latest version to have a source distribution uploaded -- you can see the file is present at https://pypi.python.org/pypi/pyfcm/0.0.4, but not at https://pypi.python.org/pypi/pyfcm/0.0.9.
When is the support for django >= 1.7 coming
Since tornado is already done
Cheers.
Hi @olucurious ,
I'm a little confused as to why the object returned by notify_multiple_devices()
is a list and not just a dictionary. I don't think we should ever get multiple response objects. According to the FCM doc, this is a sample response for a multicast message:
{ "multicast_id": 216,
"success": 3,
"failure": 3,
"canonical_ids": 1,
"results": [
{ "message_id": "1:0408" },
{ "error": "Unavailable" },
{ "error": "InvalidRegistration" },
{ "message_id": "1:1516" },
{ "message_id": "1:2342", "registration_id": "32" },
{ "error": "NotRegistered"}
]
}
And this is an example of what I receive after using notify_multiple_devices()
:
[{
'results': [
{'error': 'InvalidRegistration'},
{'error': 'InvalidRegistration'},
{'error': 'InvalidRegistration'},
{'error': 'InvalidRegistration'},
{'error': 'InvalidRegistration'},
{'error': 'InvalidRegistration'},
{'error': 'InvalidRegistration'},
{'message_id': '0:1485319787476913%c8d9d7b3f9fd7ecd'},
{'message_id': '0:1485319787476698%c8d9d7b3f9fd7ecd'},
],
'failure': 7,
'multicast_id': 5686648884823674295,
'success': 2,
'canonical_ids': 0,
}]
The enclosing list seems unnecessary because we should never get back more than one of these dictionaries, right? Any comments you have to clear this up would be much appreciated (:
One example
if data_message and isinstance(data_message, dict):
fcm_payload['data'] = data_message
another example:
if time_to_live and isinstance(time_to_live, int):
fcm_payload['time_to_live'] = time_to_live
It would be better to throw an exception or at least a big warning to stderr so that the programmer can do something about the fact that they used the wrong type.
https://github.com/olucurious/PyFCM/blob/master/pyfcm/baseapi.py#L184
Shouldn't this be response = self.do_request(payload)
?
How to send action buttons on notification like this http://i.stack.imgur.com/24I2x.png?
I wold like to send a high priority message, is it set up by default?
The FCMNotification.notify_single_device
seems to be parsing its registration_id
wrong. This doesn't work:
push_service.notify_single_service(registration_id=reg_id, ...)
but this works:
push_service.notify_single_service(registration_id=[reg_id], ...)
Hi,
i can`t find retry-after header implementation in this source code.Please help me out on this,if notification get internal server error issues.Currently i am sending notification to 20000 devices,few of them are getting this error.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.