Skip to content

Push notification doesn't get to the device #942

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rafapetter opened this issue Mar 9, 2016 · 72 comments
Closed

Push notification doesn't get to the device #942

rafapetter opened this issue Mar 9, 2016 · 72 comments

Comments

@rafapetter
Copy link

Issue
On Cloud Code I have an after save trigger that sends a Push to a specific user, but it doesn't get to the device and I neither get a GCM request and response. Any ideas?

Prerequisites

  • I've migrated to AWS Elastic Beanstalk(64bit Amazon Linux 2015.09 v2.0.7, running Node.js 4.2.3) and MongoLab
  • I'm running the 2.1.4 of Parse Server.
  • I'm testing on Android SDK
  • I've followed everything on Push tutorial here

Log from Verbose

POST /parse/push { host: 'parseserver-xxx-env.elasticbeanstalk.com',
  'x-real-ip': 'xxx',
  'x-forwarded-for': 'xxx',
  'content-length': '406',
  accept: '*/*',
  'content-type': 'text/plain',
  'user-agent': 'node-XMLHttpRequest, Parse/js1.7.1 (NodeJS 4.3.0)',
  'x-forwarded-port': '80',
  'x-forwarded-proto': 'http' } {
  "where": {
    "user": {
      "__type": "Pointer",
      "className": "_User",
      "objectId": "xxxxx"
    }
  },
  "data": {
    "alert": "Bla bla bla",
    "badge": "Increment",
    "uri": "com.xxxx.xxxx://xxxx?id=xxxxx",
    "p": "xxxxxx"
  }
}
response: {
  "response": {
    "result": true
  }
}
Push to user: xxxxx was successful

How I initialise Parse Server on index.js

var api = new ParseServer({
  databaseURI: databaseUri || 'mongodb://localhost:27017/test',
  cloud: process.env.PARSE_SERVER_CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: 'xxxxxxx',
  masterKey: 'xxxxxxx',
  fileKey: process.env.PARSE_SERVER_FILE_KEY || 'xxxxxxx',
  facebookAppIds: ['xxxxxxx'],
  serverURL: 'http://parseserver-xxxxx-env.elasticbeanstalk.com/parse/', 
  filesAdapter: new S3Adapter(
    "xxxxxxx",
    "xxxxxxx",
    "xxxxxxx",
    {directAccess: true}
  ), 
  push: {
      android: {
        senderId: 'xxxxxxx',
        apiKey: 'xxxxxxx'
      },
      ios: {
        pfx: __dirname + '/development.p12',
        bundleId: 'com.xxxxxxx.xxxxxxx',
        production: false
      },
      ios: {
        pfx: __dirname + '/production.p12',
        bundleId: 'com.xxxxxxx.xxxxxxx',
        production: true
      }
  }
});

Function on Cloud Code

var pushQuery = new Parse.Query(Parse.Installation);
        pushQuery.equalTo('user', user);
        Parse.Push.send({
            where: pushQuery,
            data: {
              alert: "Bla bla bla",
              badge: "Increment",
              uri: "com.xxxx.xxxx://xxxx?id=" + offer.id,
              p: offer.id
            }
            }, {useMasterKey: true}).then(function (result) {
              console.log("Push to user: " + user.id + " was successful");
            },
            function(error) {
              console.log("Error sending push: " + error.code + " - " + error.message);
            }
        );

Possible Similar Issues

@flovilmart
Copy link
Contributor

The where clause for push are supposedly on _Installation and not _User

@rafapetter
Copy link
Author

So if I want to send to a specific user, I need the get the Installation ID from that user and query like this?

var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo('objectId', installationId);

@flovilmart
Copy link
Contributor

You should set the userId to the installation object, and do:

var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo("userId", userId);
// OR 
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo("user", user);
``` 

@flovilmart flovilmart reopened this Mar 9, 2016
@rafapetter
Copy link
Author

Ok, but that's exactly what I did. I've set the user pointer:

pushQuery.equalTo('user', user);

@rafapetter
Copy link
Author

Here's this user _Installation data on mongodb

{
    "_id": "xxxxxx",
    "appName": "xxxxxx",
    "appVersion": "xxxxxx",
    "deviceType": "android",
    "appIdentifier": "com.xxxxxx.xxxxxx",
    "installationId": "xxxxxx",
    "pushType": "gcm",
    "timeZone": "America/Sao_Paulo",
    "localeIdentifier": "pt-BR",
    "parseVersion": "1.13.0",
    "_p_user": "_User$xxxxxx",
    "_updated_at": {
        "$date": "2016-03-09T21:45:01.254Z"
    },
    "_created_at": {
        "$date": "2016-03-09T21:45:01.254Z"
    }
}

@rafapetter
Copy link
Author

@flovilmart may I understand why you close this issue?

@flovilmart flovilmart reopened this Mar 10, 2016
@flovilmart
Copy link
Contributor

I'm no android specialist, but it looks like the deviceToken is not set on your Installation object

@mahabubakram
Copy link

I am having the same problem. As I have configured only the ios device. As my application is ios based. So I get the error in push. this is the log.

{ params: { id: '45J1QIaKIi' },
  master: false,
  user: ParseUser { _objCount: 0, className: '_User', id: '45J1QIaKIi' },
  installationId: '82e1d517-7aac-d887-d02b-e407c3de5e7f' }
##### PUSH OK
Can not find sender for push type android, {"where":{"deviceType":"ios","channels":"user_45J1QIaKIi"},"data":{"alert":"Sending push notification"}}
APNS Connection 0 Socket Error
APNS Connection 0 Socket Error
APNS Connection 0 Socket Error
APNS Connection 0 Disconnected

I dont get push on my device. How to solve this problem.

@rafapetter
Copy link
Author

@flovilmart good point, there's no deviceToken column on _Installation for users who were created after the migration. Any idea why the parse-server might not be creating it? Look at this POST sent from user's first login:

POST /parse/classes/_Installation { host: 'parseserver-xxxxx-env.elasticbeanstalk.com',
  'x-real-ip': 'xxxxx',
  'x-forwarded-for': 'xxxxx',
  'content-length': '326',
  'accept-encoding': 'gzip',
  'content-type': 'application/json',
  'user-agent': 'Parse Android SDK 1.13.0 (com.xxxxx.xxxxx/7) API Level 16',
  'x-newrelic-id': 'xxxxx==',
  'x-parse-app-build-version': '7',
  'x-parse-app-display-version': '1.1.3.2',
  'x-parse-application-id': 'xxxxx',
  'x-parse-client-key': 'xxxxx',
  'x-parse-client-version': 'a1.13.0',
  'x-parse-installation-id': 'xxxxx',
  'x-parse-os-version': '4.1.2',
  'x-parse-session-token': 'r:xxxxx',
  'x-forwarded-port': '80',
  'x-forwarded-proto': 'http' } {
  "appName": "xxxxx",
  "appVersion": "1.1.3.2",
  "deviceType": "android",
  "appIdentifier": "com.xxxxx.xxxxx",
  "installationId": "xxxxx",
  "pushType": "gcm",
  "timeZone": "America/Sao_Paulo",
  "localeIdentifier": "pt-BR",
  "parseVersion": "1.13.0",
  "user": {
    "__type": "Pointer",
    "objectId": "g83vqLMR0N",
    "className": "_User"
  }
}
response: {
  "status": 201,
  "response": {
    "objectId": "XRR1BEqCZa",
    "createdAt": "2016-03-09T21:45:01.254Z"
  },
  "location": "http://parseserver-xxxxx-env.elasticbeanstalk.com/parse/classes/_Installation/XRR1BEqCZa"
}

And also just for testing I went on mongodb and updated an user _Installation with a deviceToken. And now when trying to push I got this MismatchSenderId error:

GCM request and response {"request":{"params":{"priority":"normal","data":{"time":"2016-03-10T12:17:50.894Z","push_id":"84kHd9B0fX","data":"{\"alert\":\"Bla bla bla\",\"uri\":\"com.xxxx.xxxx://offer?id=kHrtmMOeYF\",\"p\":\"kHrtmMOeYF\"}"}}},"response":{"multicast_id":xxxx,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}}

@rafapetter
Copy link
Author

hey @mahabubakram, your error message looks similar to mine. They have a problem with the sender. Can you check if there's this column deviceToken on your db?

GCM: MismatchSenderId
APNS: Can not find sender for push type android

@mahabubakram
Copy link

@weengo , I am trying to send to an old user. Who is already there in my parse database. So after migration to mongo lab I am trying to send push notification to that user and I have deviceToken to that user. But as you can see push is not going into the device. And I am having this problem for quite a long time but no one has given response on it.

@rafapetter
Copy link
Author

Ok, got it solved. On my android manifest file I was using the API key, instead of Sender Id. And I was also using key of type Android, but I have now changed to one of type server. So anyone with similar issue remember to check that on the google console.

Now my _Installation is receiving the deviceToken normally.

And oddly I'm still getting the GCM error:

GCM request and response {"request":{"params":{"priority":"normal","data":{"time":"2016-03-10T15:07:40.144Z","push_id":"xxxxxxx","data":"{\"alert\":\"bla bla bla\",\"uri\":\"com.xxxxxxx.xxxxxxx://offer?ofid=xxxxxxx\",\"p\":\"xxxxxxx\"}"}}},"response":{"multicast_id":xxxxxxx,"success":1,"failure":2,"canonical_ids":0,"results":[{"error":"MismatchSenderId"},{"error":"MismatchSenderId"},{"message_id":"0:xxxxxxx"}]}}

@mahabubakram I would suggest you create a new user on mongodb, and try to send push to this new user.

@karkaletsis
Copy link

I have the same problem. The notification doesn't reach to device. I run parse server example and try to send notification using rest api

curl -X POST
-H "X-Parse-Application-Id: myOtherAppId"
-H "X-Parse-Master-Key: myMasterKey"
-H "Content-Type: application/json"
-d '{
"userId": "8JKVn0ummZERXG53hre2GA==",
"deviceType": "android",
"channels": [
"kostas"
],
"data": {
"title": "Test",
"alert": "Test"
}
}'
http://localhost:9999/myparseapp/push

The rest response is {"result":true}. I don't see any log in the server and I wonder what is wrong. I am using parse-server 2.2.2

@rafapetter
Copy link
Author

@karkaletsis can you show how you're declaring the push on your index.js file?

@karkaletsis
Copy link

@weengo I refer it like this

var api = new ParseServer({
databaseURI: 'mongodb://localhost:27017/dev',
cloud: __dirname + '/cloud/main.js',
appId: 'myOtherAppId',
masterKey: 'myMasterKey',
serverURL: 'http://10.0.0.1:9999/myparseapp',
push: {
android: {
senderId: '408817503931',
apiKey: 'AIzaSyBtzYPBj6r6ZDmpUMOhTmNV85QZZbeKIwM'
},
ios: {
pfx: '/home/ubuntu/git/Certificates_PushNotification_Prod.p12',
bundleId: '11',
production: false
}
}

@flovilmart
Copy link
Contributor

Bundle id should be you CFBundleIdentifier from your iOS app

@karkaletsis
Copy link

I try to test only android push for now and so I places a random key in bundleId

@rafapetter
Copy link
Author

@karkaletsis, are you sure to be using a Server key from Google?

Does your android manifest has something like this? The XXXX being you senderId:

<meta-data android:name="com.parse.push.gcm_sender_id" android:value="id:XXXX"/>

@karkaletsis
Copy link

Yes, I have this in my android maniferst xml this entry. Didn't I have to see something in error log both in parse server and google developer logs?

@otymartin
Copy link

Yes i have the same problem. On the client side, the push is successfully sent but the device doesn't receive it. Im thinking of just using onesignal.com since parse's push notifications does not support "high throughput" to better invest in a more longterm solution. I'd still like to debug the issue to learn why its not working.

@rafapetter
Copy link
Author

@karkaletsis I believe you do should see something only if the message is actually being sent. When you run with VERBOSE=1 don't you get nothing?

@rafapetter
Copy link
Author

@otymartin Could you also run with VERBOSE=1 so we can see what's message when the push is sent?

@karkaletsis
Copy link

How do I enable VERBOSE=1, to curl that posts the message or to the server? and how?

@otymartin
Copy link

@weengo How do I do that? I only started learning javascript since the migration so Its a complete gray area.

    // MARK: - SEND PUSH NOTIFICATION
    func sendPushToContact(contact: PFUser) {
        PFCloud.callFunctionInBackground("sendPushToContact", withParameters: ["user": contact.objectId!, "params": (PFUser.currentUser()?.valueForKey("name"))!], block: { (result: AnyObject?, error: NSError?) in
            if error == nil {
                //THIS SUCCEEDS :)
                print("Client: Push Sent")
            } else {
                print("Client: Push Failed")
                print(error?.localizedDescription)
            }
        })
    }
//SEND PUSH NOTIFICATIONS
Parse.Cloud.define("sendPushToContact", function(request, response) {

  // request has 2 parameters: params passed by the client and the authorized user
  var params = request.params;
  var user = request.user;

  // Our "Message" class has a "text" key with the body of the message itself
  var messageText = params.text;

  var pushQuery = new Parse.Query(Parse.Installation);
  pushQuery.equalTo('user', user); // targeting incomingUser
  pushQuery.equalTo('deviceType', 'ios'); // targeting iOS devices only

  Parse.Push.send({
    where: pushQuery, // Set our Installation query
    data: {
      alert: "Message: " + messageText
    }
  }, { success: function() {
      console.log("#### PUSH OK");
  }, error: function(error) {
      console.log("#### PUSH ERROR" + error.message);
  }, useMasterKey: true});
  response.success('success');
});

@sekharrockz
Copy link

@Heman6886 i am waiting for your response. can you please help me out with this issue

@HemanParbhakar
Copy link

Actually u cannot send push to an installation id

@sekharrockz
Copy link

sekharrockz commented Apr 19, 2016

@Heman6886
ok. I tried with this cloud code as well. its still not working.

snip20160419_18

@benitech
Copy link

benitech commented Apr 19, 2016

Ok, so i have this same problem.

I am trying with a clean Parse Starter Project with only the exact AndroidManifest.xml additions as specified in "https://github.com/ParsePlatform/Parse-Server/wiki/Push-Configuring-Clients" and i have configured my Parse-Server exactly as specified in "https://github.com/ParsePlatform/parse-server/wiki/Push".

I am running my own Parse-Dashboard and trying to use that to send a push notification to my android device running the Parse Starter app. Also trying to use the "curl example".

Nothing. Nada. What's going on?

How do i enable logging inside index.js file to check what's happening? I don't see anything in /logs nor do i see any "_Push folders" being created in my mongo, as f@flovimart commented elsewhere.

I am pretty sure my keys and app setup is done proper. I have followed the examples to the T.

@flovilmart
Copy link
Contributor

Start your server with VERBOSE=1 as an environment variable and send out the logs related to push sending.

@benitech
Copy link

benitech commented Apr 19, 2016

i'd love to. just can't figure out how to pass that variable directly from inside "index.js". I am running my parse-server on CentOS 7 with nvm and node v 5.10.1 with simple "node index.js" or "pm2 start index.js"

EDIT: I started parse-server with pm2 and passing a json config file with the VERBOSE=1 option inside. Save a file with the following inside, and start with "pm2 start /path/to/this/config/file.json"

{
"apps": [
{
"script": "path-to-parse-server-folder/index.js",
"log_file": "logs/server.log",
"error_file": "logs/server-error.log",
"log_date_format" : "YYYY-MM-DD HH:mm:ss Z",
"instances": 1,
"watch": true,
"ignore_watch": ["cloud", "logs"],
"env": {
"VERBOSE": "1"
}
}
]
}

@flovilmart
Copy link
Contributor

this is an environment variable so, wither VERBOSE=1 node index.js, or in your pm2 configuration

@benitech
Copy link

Logs: From curl. Pretty much similar using Dashboard.

verbose: POST /parse/push { 'user-agent': 'curl/7.29.0',
host: 'My-Server-IP:Port',
accept: '/',
'x-parse-application-id': 'My-Key',
'x-parse-master-key': 'My-Key',
'content-type': 'application/json',
'content-length': '311' } {
"where": {
"deviceType": {
"$in": [
"ios",
"android"
]
}
},
"data": {
"title": "The Shining",
"alert": "All work and no play makes Jack a dull boy."
}
}
verbose: {
"headers": {
"X-Parse-Push-Status-Id": "JPgxVmHgoL"
},
"response": {
"result": true
}
}
verbose: sending push to 2 installations
verbose: sent push! 0 success, 0 failures

@flovilmart
Copy link
Contributor

does the device have the proper deviceTokens?

@benitech
Copy link

benitech commented Apr 19, 2016

Android installation does not add any device tokens. I used the exact tutorial to add the following in a clean ParseStarterProject.

// Native: Application.java
public void onCreate() {
// ...
ParseInstallation.getCurrentInstallation().saveInBackground();
}

Though after the latest "parse-server" update to 2.2.7, i notice the schema added more fields such as "DeviceToken, Channels, GcmSender, PushType, Badge".

These did not show up in the earlier version "2.2.6".

My New installs on a android device, show these fields as empty, though both app and parse-server side are properly configured with GCM ID/Keys.

@flovilmart
Copy link
Contributor

does the GCMSender is set? I'm wondering here as there are many users with valid and functioning configurations.

@benitech
Copy link

benitech commented Apr 19, 2016

Of course. In my Parse-Server i have set:

push: {
android: {
senderId: '11112222233333', // The Sender ID of GCM
apiKey: 'ABC123DEF456GHI789JKF' // The Server API Key of GCM
}
},

here - "senderId is the project ID". "apiKey is the server api key given by google dev console"

@flovilmart
Copy link
Contributor

Try to ask over stack overflow. With VERBOSE=1 you should also have logs from the GCM adapter itself. Seems that it's improperly configured to me.

@benitech
Copy link

ok. will do.

it's just that we don't really have an active community over on stackoverflow for now. most queries/replies are still related to the older parse.com and lead to a frustrating experience going round in circles.

@HemanParbhakar
Copy link

@benitech did u use custom reciever for recieving push notification

@benitech
Copy link

no. just added the "ParseInstallation.getCurrentInstallation().saveInBackground();" in the android client side code, as the tutorial says

@HemanParbhakar
Copy link

have u declare the server url in application activity and which parse library are you using

@benitech
Copy link

you mean, am i connecting to my own parse-server properly? of course. It works fine for other things, i can see my installations and sessions from the starter app right away.

Parse.initialize(new Parse.Configuration.Builder(getBaseContext()).applicationId("My-Key").server("http://My-Server-IP:Port/parse/").build());
ParseInstallation.getCurrentInstallation().saveInBackground();
ParseUser.enableAutomaticUser();
ParseACL defaultACL = new ParseACL();

And so far, with Parse-Server, only Parse 1.13.0 can be used.

dependencies {
compile 'com.parse.bolts:bolts-android:1.+'
compile 'com.parse:parse-android:1.+'
}

@HemanParbhakar
Copy link

Please run npm start enable verbose

VERBOSE=1 DEBUG=apn,node-gcm npm start

@benitech
Copy link

Same as i posted earlier.

verbose: POST /parse/push { 'user-agent': 'curl/7.29.0',
host: 'My-Server-IP:Port',
accept: '/',
'x-parse-application-id': 'My-Key',
'x-parse-master-key': 'My-Key',
'content-type': 'application/json',
'content-length': '288' } {
"where": {
"deviceType": {
"$in": [
"android"
]
}
},
"data": {
"title": "The Shining",
"alert": "All work and no play makes Jack a dull boy."
}
}
verbose: {
"headers": {
"X-Parse-Push-Status-Id": "JZIN15X0aM"
},
"response": {
"result": true
}
}
verbose: sending push to 3 installations
verbose: sent push! 0 success, 0 failures

@HemanParbhakar
Copy link

no device is registered that is the reason please reverify the project id and app key of GCM

@sekharrockz
Copy link

sekharrockz commented Apr 20, 2016

@Heman6886
It is working now. Thanks for the help.

Actually i updated my parse server to the latest one and it started working. Still there needs to be a proper documentation for others to understand.

It was so much of time loss for me, just to make this work. Parse developers need to contribute to these issues and make sure it works for everyone.

@HemanParbhakar
Copy link

ok

@sekharrockz
Copy link

sekharrockz commented Apr 20, 2016

@Heman6886
One more thing, we can call push from rest api's also.

@benitech
Copy link

I'll add a Working Sample for both Parse-Server and Parse-Starter project on my github later. Might help others with any number of config issues in either.

@HemanParbhakar
Copy link

@sekharrockz yes using cloud code

@lifeisfunny
Copy link

lifeisfunny commented Jul 14, 2016

O god , The Push Section is a mess , Yet You guys did a fantastic job on bring parse to public !
However , i am encounter a issue when i put push query in aftersave function , I got result success but nothing else T-T . Does anyone else have this problem ??

does my after send
verbose: {
"response": {
"updatedAt": "2016-07-14T17:51:34.864Z"
}
}

How did this even happened LOL I literally got nothing to work with LOL!
Please some one give me a hint And thank your all for doing a great job !

@lifeisfunny
Copy link

By the way , This is my afterSave Block :`Parse.Cloud.afterSave("OBJECTCLASS",function(req,res){
console.log("does my after send");
var user = req.object.relation("requestUser").query();
user.notContainedIn("objectId",req.object.get("rejectUserList"));

var pushQuery = new Parse.Query(Parse.Installation);

pushQuery.matchesQuery('user',user);

Parse.Push.send({
where: pushQuery ,
data: {
alert: 'Test',
//sound: 'default'
}
}, {
useMasterKey: true,
success: function(object) {
// Push sent!
console.log(object);
res.success();
},
error: function(error) {
console.log(error.message);
res.error(error.message);
// There was a problem :(
}
});
});`

@jorgemendiza
Copy link

Hello!
I had the same issue. I delete the line "res.success();" or "response.success();" and the pushes are send.

@flovilmart
Copy link
Contributor

There is no response object passed as a second argument in afterSave

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests