I got this Unauthorized null message when I try trigger node script for my push notification.
I'm using this sample code for my push notification.
https://github.com/hollyschinsky/PushNotificationSample30/
Please refer this site for your reference.
http://devgirl.org/2013/07/17/tutorial-implement-push-notifications-in-your-phonegap-application/
I already check this solution but it still didn't work. Why?
node.js returns null push messages
After I insert the correct API key, we got authorised but null.
Actually "null" in the case means it is a success. The problem is when you run your application in local environment and the device is connected to wifi. There is a certain case that firewall block the traffic from the outgoing connection ports which are used by GCM (5228,5229,5230).
You can refer to the site as a reference
http://developer.android.com/google/gcm/http.html
Looks like you have not registered for an api key. This is from the url you posted.
var gcm = require('node-gcm');
var message = new gcm.Message();
//API Server Key
var sender = new gcm.Sender('AIzaSyCDx8v9R0fMsAsjoAffF-P3FCFWXlvwLhg');
var registrationIds = [];
// Value the payload data to send...
message.addData('message',"\u270C Peace, Love \u2764 and PhoneGap \u2706!");
message.addData('title','Push Notification Sample' );
message.addData('msgcnt','3'); // Shows up in the notification in the status bar
message.addData('soundname','beep.wav'); //Sound to play upon notification receipt - put in the www folder in app
//message.collapseKey = 'demo';
//message.delayWhileIdle = true; //Default is false
message.timeToLive = 3000;// Duration in seconds to hold in GCM and retry before timing out. Default 4 weeks (2,419,200 seconds) if not specified.
// At least one reg id required
registrationIds.push('APA91bwu-47V0L7xB55zoVd47zOJahUgBFFuxDiUBjLAUdpuWwEcLd3FvbcNTPKTSnDZwjN384qTyfWW2KAJJW7ArZ-QVPExnxWK91Pc-uTzFdFaJ3URK470WmTl5R1zL0Vloru1B-AfHO6QFFg47O4Cnv6yBOWEFcvZlHDBY8YaDc4UeKUe7ao');
/**
* Parameters: message-literal, registrationIds-array, No. of retries, callback-function
*/
sender.send(message, registrationIds, 4, function (result) {
console.log(result);
});
Related
According to the documentation,
The Push API gives web applications the ability to receive messages pushed to them from a server, whether or not the web app is in the foreground, or even currently loaded, on a user agent.
If properly implemented, this seems to suggest that Android Firefox would be able to handle push notifications, even though the app is in the background.
Indeed, this works completely fine for me on Android Chrome, but for Android Firefox, as soon as the browser has been in the background for a short period of time (a couple of hours seems to be enough on the Android 10 devices I tested this on), push notifications stop coming through, and they do not even show up once the browser is loaded again, even if I specify a TTL of 60*60*24.
More concretely, I have examples of users that subscribe to web push messages, and when sending the messages to the Mozilla push server, I'll always get 201 responses. The messages show up just fine when the browser is in the foreground, but again, after a while in the background, they'll stop showing up. I've specified "normal" for the "Urgency" header, and the output of Python's int(time.time()) + (12 * 60 * 60) for the VAPID expiry time.
I first suspected the TTL to be the culprit, but according to this blog post, I shouldn't be getting 201s if that were the issue.
My service worker looks as follows:
self.addEventListener("push", function(event) {
if (event.data) {
data = event.data.json()
showLocalNotification(data.title, data.message, self.registration);
}
});
const showLocalNotification = (title, body, swRegistration) => {
const options = {
body: body,
badge: "/badge.png",
icon: "/plug-512.png",
};
swRegistration.showNotification(title, options);
};
I've tried adding a trivial event handler for fetch but that makes no difference either.
I use pywebpush to make the requests to the push servers and py_vapid to handle signing; the concrete implementation takes a string called data and the user-provided subscription_info, and creates a request as follows:
import time
from urllib.parse import urlparse
from pywebpush import WebPusher
from py_vapid import Vapid
def send_push(data, subscription_info):
subscription_info = row
pusher = WebPusher(subscription_info)
url = urlparse(subscription_info['endpoint'])
aud = "{}://{}".format(url.scheme, url.netloc)
vapid_claims = {'sub': 'mailto:mail#example.com'}
vapid_claims['aud'] = aud
vapid_claims['exp'] = int(time.time()) + (12 * 60 * 60)
vv = Vapid.from_string('my-key')
vapid_headers = vv.sign(vapid_claims)
vapid_headers['Urgency'] = 'normal'
resp = pusher.send(data, vapid_headers, ttl=60*60*24)
assert resp.status_code == 201
The app is currently live here.
I am using python gcm for Django.response=json.dumps(gcm.json_request(registration_ids=reg_ids,data=data)).response is always NULL. But message is sent
Their documentation suggested:
response=json.dumps(gcm.json_request(registration_ids=reg_ids,data=data))
Well! Message is received to mobile successfully. But the problem is response value is always empty.
My code:
def sendNotification(request):
gcm = GCM('AIzXXXXXXXXXXXXXXXXXXX')
reg_ids=[]
devices=Devices.objects.all()
for device in devices:
reg_ids.append(device.gcm_reg_id)
data = {'sender': "someone",'message':"Cool!",}
response=json.dumps(gcm.json_request(registration_ids=reg_ids,data=data))
return HttpResponse(response)
I just had my first contacts with the ionic framework. I've worked with Phonegap and AngularJS before however, so it was not all that new to me.
I found out that there is this new feature to use Google Cloud Messaging push notifications in Ionic, through the Ionic Push feature (http://blog.ionic.io/announcing-ionic-push-alpha/).
Related lines of code from app.js
angular.module('starter', ['ionic','ionic.service.core', 'starter.controllers', 'starter.services'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleLightContent();
}
// enable push notifications
Ionic.io();
// enable users (http://docs.ionic.io/docs/user-quick-start)
// this will give you a fresh user or the previously saved 'current user'
var user = Ionic.User.current();
// if the user doesn't have an id, you'll need to give it one.
if (!user.id) {
user.id = Ionic.User.anonymousId();
// user.id = 'your-custom-user-id';
}
console.log('user-id:' + user.id);
//persist the user
user.save();
var push = new Ionic.Push({
"debug": true,
"onNotification": function(notification) {
var payload = notification.payload;
console.log(notification, payload);
},
"onRegister": function(data) {
console.log(data.token);
}
});
push.register(function(token) {
console.log("Device token:",token.token);
});
push.addTokenToUser(user);
console.log('token added to user');
});
})
Log from ionic serve
ionic $ 0 361081 log Ionic Core:, init
1 361083 log Ionic Core:, searching for cordova.js
2 361085 log Ionic Core:, attempting to mock plugins
3 361155 log user-id:1cc3d21c-b687-4988-b944-ad07b1a677c8
4 361158 log Ionic Push:, a token must be registered before you can add it to a user.
5 361159 log Ionic Push:, token is not a valid Android or iOS registration id. Cannot save to user.
6 361159 log token added to user
7 361160 log Ionic Push:, register
8 361160 error ReferenceError: PushNotification is not defined, http://localhost:8100/lib/ionic-platform-web-client/dist/ionic.io.bundle.min.js, Line: 2
9 361526 log Ionic User:, saved user
Any input is welcome, I am also more than happy to provide more information if needed.
EDIT 10/05/2015:
found out that dev_push = false only works on physical devices, not in browser
I tried to add token to user before even registering the user
I'm having the same problem, seems not many answers online at the moment.
but even on real device, it won't save the token to user.
I just had to decide go live without push first, then use ionic deploy to follow up.
also I think you have to put this line
push.addTokenToUser(user);
inside the register callback according to this doc
http://docs.ionic.io/docs/push-usage
You also need to declare 'ionic.service.push' as a dependency in your angular module if you'd like to use it.
angular.module('starter', ['ionic','ionic.service.core', 'ionic.service.push'])
I have it like this and it works:
Ionic.io();
var user = Ionic.User.current();
if (!user.id) {
user.id = Ionic.User.anonymousId();
// save our newly created user
user.save();
}
var push = new Ionic.Push({});
push.register(function (token) {
console.log("Got Token:", token.token);
// now we have token, so add it to user
push.addTokenToUser(user);
// don't forget to save user to Ionic Platform with our new token
user.save();
});
// set this user as current, so we can acess him later
Ionic.User.current(user);
Did you use this
ionic config set dev_push true-if testing in emulator or laptop
ionic config set dev_pushfalse - if testing on the phone
ionic push --google-api-key Your API Key
ionic config set gcm_key Project Number
Your token is the registration id that is unique for a particular device. That is sent to you by android.
Your Phone (With the API Key)---------> to Google's GCM
Google GCM (recognises it's you via your Project number and API key) -----> Oh it's you let me make a note of it. (Save a token id in it's DB and send's one to you.)
You get a registration id unique for your device(will change if an app is uninstalled).
You call your server say hey it's me your user. Please Notify me if you get something.
Server obliges, says, okay dude, I got this. Saves the registration id with your details probably your username in it's DB.
Now from Server.
I need to inform my users about a great deal(or an accident or something).
Pull up all targeted registration Id's from DB(maybe on some condition)
registrationIds.push(regId) //in a loop
and sender.send(message, registration, function(err, result){
});
Send to Google. Google see's oh only these many people(not all maybe) from this API Key need a notification. no Problem I will notify them and you receive a notification, my dear friend.
As mentioned in the link , Adding token to the $ionicUser is done by doing , user.addPushToken(pushToken); .
For this to work you should first configure the app not to use developement pushes by ,
ionic config set dev_push true
After initialising Ionic.io and Ionic.push , load the user or create one with a new random id ,
Ionic.io();
var push = new Ionic.Push();
Ionic.User.load(localStorage.id).then(function (user) {
Ionic.User.current(user);
pushFactory.register(push, user);
}, function (error) {
/*the user with that id is not present , so create one with a random id and register the push */
});
The push factory is defined as below,
function pushFactory() {
return {
'register': function (push, user) {
push.register(function (pushToken) {
user.addPushToken(pushToken);
user.save().then(function (answer) {
console.log('user saved'+answer);
})
})
}
}
}
For a while now, I have been trying to figure out how to send push notifications. The app I have made is for Android right now, but I want to extend it to other devices once I figure this out. I've looked into various services, such as Amazon SNS, but they all neglect to include how to get the device token. They all assume you know how to do that.
So what I am asking is: how do I get a device token/registration ID for a device?
I tried using this code:
var tokenID = "";
document.addEventListener("deviceready", function(){
//Unregister the previous token because it might have become invalid. Unregister everytime app is started.
window.plugins.pushNotification.unregister(successHandler, errorHandler);
if(intel.xdk.device.platform == "Android")
{
//register the user and get token
window.plugins.pushNotification.register(
successHandler,
errorHandler,
{
//senderID is the project ID
"senderID":"",
//callback function that is executed when phone recieves a notification for this app
"ecb":"onNotification"
});
}
else if(intel.xdk.device.platform == "iOS")
{
//register the user and get token
window.plugins.pushNotification.register(
tokenHandler,
errorHandler,
{
//allow application to change badge number
"badge":"true",
//allow application to play notification sound
"sound":"true",
//register callback
"alert":"true",
//callback function name
"ecb":"onNotificationAPN"
});
}
}, false);
//app given permission to receive and display push messages in Android.
function successHandler (result) {
alert('result = ' + result);
}
//app denied permission to receive and display push messages in Android.
function errorHandler (error) {
alert('error = ' + error);
}
//App given permission to receive and display push messages in iOS
function tokenHandler (result) {
// Your iOS push server needs to know the token before it can push to this device
// here is where you might want to send the token to your server along with user credentials.
alert('device token = ' + result);
tokenID = result;
}
//fired when token is generated, message is received or an error occured.
function onNotification(e)
{
switch( e.event )
{
//app is registered to receive notification
case 'registered':
if(e.regid.length > 0)
{
// Your Android push server needs to know the token before it can push to this device
// here is where you might want to send the token to your server along with user credentials.
alert('registration id = '+e.regid);
tokenID = e.regid;
}
break;
case 'message':
//Do something with the push message. This function is fired when push message is received or if user clicks on the tile.
alert('message = '+e.message+' msgcnt = '+e.msgcnt);
break;
case 'error':
alert('GCM error = '+e.msg);
break;
default:
alert('An unknown GCM event has occurred');
break;
}
}
//callback fired when notification received in iOS
function onNotificationAPN (event)
{
if ( event.alert )
{
//do something with the push message. This function is fired when push message is received or if user clicks on the tile.
alert(event.alert);
}
if ( event.sound )
{
//play notification sound. Ignore when app is in foreground.
var snd = new Media(event.sound);
snd.play();
}
if ( event.badge )
{
//change app icon badge number. If app is in foreground ignore it.
window.plugins.pushNotification.setApplicationIconBadgeNumber(successHandler, errorHandler, event.badge);
}
}
All I get is an alert that says "result = ok". The alerts later on in the code don't happen. I've tried making sense of the code but I'm not getting anywhere. Any suggestions? Is there a tutorial for this I'm not finding?
Those legacy intel.xdk functions are being retired (the will continue to live in an 01.org, see the notice on this page: https://software.intel.com/en-us/node/492826).
I recommend you investigate one of the many push notification Cordova plugins that are available. Use your favorite web search tool to search for something like "cordova phonegap push notification plugin" to find some. The good ones will have examples of how to use.
Note:-
Unregister - Its not strictly necessary to call it.....
Ensure that you have a sender ID for Android (no idea about iOS).
Result OK means that the plugin is installed correctly and has run properly.
Problems could be due to:
Incorrect sender ID
Testing in emulator without adequate setup
Important - Push notifications are intended for real devices. They are not tested for WP8 Emulator. The registration process will fail on the iOS simulator. Notifications can be made to work on the Android Emulator, however doing so requires installation of some helper libraries, as outlined here, under the section titled "Installing helper libraries and setting up the Emulator".
onNotification must be available as a global object. So try attaching it to the window. Refer to this question
Examples of properly initializing PushPlugin in:
Ionic (my answer)
I am using rapns to provide GCM and APNS support. For APNS, I know what unregistered device I must delete via on.apns_feedback (rapns.rb):
on.apns_feedback do |feedback|
device = AppleDevice.find_by_token(feedback.device_token)
device.destroy if device
end
but for GCM, I can't find a way to know what device is unregistered so I can delete it from my database.
I tried with the reflection API, but I'm not getting on.notification_failed and on.error called whenever a Rapns::DeliveryError exception is raised and those methods doesn't seem to give me a way to know the unregistered tokens.
I tried catching the Rapns::DeliveryError, but it doesn't seem to work.
messenger = PushMessenger::Gcm.new
GoogleDevice.find_in_batches :batch_size => 1000 do |devices|
tokens = devices.map(&:token)
begin
messenger.deliver(app, tokens, payload, nil, true)
rescue Rapns::DeliveryError => error
GoogleDevice.destroy_all # Just to see it works
end
end
PushMessenger:
module PushMessenger
class Gcm
def deliver(app, tokens, payload, collapse_key=nil, delay_while_idle=nil, expiry=1.day.to_i)
tokens = *tokens
n = Rapns::Gcm::Notification.new
n.app = app
n.registration_ids = tokens
n.collapse_key = collapse_key
n.delay_while_idle = delay_while_idle
n.expiry = expiry
n.data = payload
n.save!
end
end
end
How can I know the token for these unregistered devices so I can remove them from my database?
I'm using rapns to do pretty much the same, so here my two cents:
First, for Android devices you don't need the device_token to deactivate/remove the device (On GCM device_token == registration_id). You can get that registration_id from the on.notification_failed callback with the Reflection API.
Last, which version of rapns are you using? Right now the last version (3.4.1) has a bug with on.notification_failed, but version 3.3.2 works just fine and you'll be able to do something like:
on.notification_failed do |notification|
device = Device.find_by_token(notification.registration_ids.first)
device.destroy if device
end
Hope that helps.