Im using fcm-node i tried to send a push notification and it perfectly works locally, however when i try to send it using the server, it fails
var message = {
//this may vary according to the message type (single recipient, multicast, topic, et cetera)
to: notificationToken,
notification: {
bla bla
},
};
fcm.send(message, function (err, response) {
console.log("inside");
if (err) {
console.log("Something has gone wrong!", err);
} else {
console.log("Successfully sent with response: ", response);
}
});
Response for server:
Successfully sent with response: {
results: [ { error: [FirebaseMessagingError] } ],
canonicalRegistrationTokenCount: 0,
failureCount: 1,
successCount: 0,
multicastId: 502625035652113000
}
Tried to get the device notified
Azure Notification Hub Exception: not able to register device entries.. the request could not be completed. we are using node js to register
You can use below code to register device entries.
Related posts and documents:
1. Issue with notification hub
2. createRegistrationId(callback)
/**
* Creates a registration identifier.
*
* #param {Function(error, response)} callback `error` will contain information
* if an error occurs; otherwise, `response`
* will contain information related to this operation.
*/
NotificationHubService.prototype.createRegistrationId = function (callback) {
validateCallback(callback);
var webResource = WebResource.post(this.hubName + '/registrationids');
webResource.headers = {
'content-length': null,
'content-type': null
};
this._executeRequest(webResource, null, null, null, function (err, rsp) {
var registrationId = null;
if (!err) {
var parsedLocationParts = url.parse(rsp.headers.location).pathname.split('/');
registrationId = parsedLocationParts[parsedLocationParts.length - 1];
}
callback(err, registrationId, rsp);
});
};
Using the azure-sb node.js module, you should be able to register a device and send to it directly. This requires a connection string and hub, as well as a device token, depending on the platform such as APNS.
import { NotificationHubService } from 'azure-sb';
const CONNECTION_STRING = ''; // Full Access Connection String
const HUB_NAME = ''; // Notification Hub Name
const APNS_TOKEN = ''; //APNS Token
const APNS_MESSAGE = {
aps: {
alert: "Notification Hub test notification"
}
};
service.apns.createNativeRegistration(APNS_REGISTRATION_ID, SAMPLE_TAG, (err, response) => {
if (err) {
console.log(err);
return;
}
console.log('Registration success');
console.log(JSON.stringify(response));
service.apns.send(SAMPLE_TAG, APNS_MESSAGE, (error, res) => {
if (error) {
console.log(error);
return;
}
console.log('Message sent');
console.log(JSON.stringify(res));
});
});
When this runs, it should register the device and send to it. I have run this very recently and works without a hitch. The older azure module might be tied to earlier TLS 1.0/1.1, which has since been deprecated for usage on Azure.
how to display Commands results in IoT Central - Commands page?
Flow:
Command sent to Device
Device received the command and returns Payload:
{
"status": 200,
"payload": {
"command": "ping",
"result_code": "ok",
"result_data": "ping 5 ms"
}
}
How to display this data in IoT Central?
Now IoT Central shows only default "Sent at ..." message.
If you set a reported property with the same name as the command when you handle the command on the device, then you can set a value that displays in the IoT Central UI. For example, using Node.js you can create a handler for a countdown method like this:
function onCountdown(request, response) {
console.log('received a request for Countdown');
console.log(JSON.stringify(request.payload, null, 2));
var fakeResponsePayload = {
key: 'value'
};
response.send(200, fakeResponsePayload, function (err) {
if (err) {
console.error('Unable to send method response: ' + err.toString());
} else {
console.log('response to Countdown sent.');
client.getTwin(function(err, twin) {
if (err) {
console.error('could not get twin');
} else {
console.log('twin created');
var patch = {
countdown:{
value: 18
}
};
twin.properties.reported.update(patch, function(err) {
if (err) {
console.error('unable to update twin: ' + err.toString());
} else {
console.log('twin state reported');
}
});
}
});
}
});
}
client.onDeviceMethod('countdown', onCountdown);
Note that the name of the field name of the command is countdown.
There is also a C++ example here: https://github.com/Azure/iot-central-firmware/blob/master/MXCHIP/mxchip_advanced/src/registeredMethodHandlers.cpp
Steps:
Create Azure mobile app with node.js backend. (server)
Create NotificationHub associated to the new mobile app. (server)
Create WinJS App (Universal Windows) in Visual Studio (client)
Associate app with App Store VS > Project > Store > Associate App with Store (client)
Include Mobile Services MobileServices.Web.js to connect with mobile services backend (client)
Connect to mobile service backend (client = new WindowsAzure.MobileServiceClient('https://.azurewebsites.net') (client)
I am having a problem trying to get the tags for push notification hub that is tied to my azure mobile service node.js backend.
I am following this blog post:
https://blogs.msdn.microsoft.com/writingdata_services/2016/04/14/adding-push-notification-tags-from-a-node-js-backend/
on how to create tags on the node.js backend.
When I call the createTags API I am presuming the tag is being created because there is no error being returned.
But when I call getTags API my error routine is firing with the error
An error occurred when retrieving installation
Error: 404 - Installation not found.TrackingId:0615f100-35fe-496e-b63d-53d39d7e1cf9_G1,TimeStamp:10/27/2016 9:46:25 PM
I can't figure out why I am getting this error?
Can anyone see what I am missing or need to do to fix this problem?
Any help would be appreciated.
createTags.js
module.exports = {
"post": function (req, res, next) {
// Get the notification hub used by the mobile app.
var push = req.azureMobile.push;
console.log('create tags installationId ' + req.body.installationId);
console.log('tags ' + req.body.tags.toString());
// Validate for and block any SID tags.
for (var i = 0; i < req.body.tags.length; i++) {
if (req.body.tags[i].search("sid:") !== -1) {
res.status(403)
.send("You cannot set '" + req.body.tags[i] + "' as a tag.");
return;
}
}
// Define an update tags operation.
var updateOperation = [{
"op": "add",
"path": "/tags",
"value": req.body.tags.toString()
}];
// Update the installation to add the new tags.
push.patchInstallation(req.body.installationId, updateOperation, function(error, response){
if(error){
console.log('An error occurred when adding tags\n\n' + error);
res.status(error.statusCode).send(error.detail);
}
else res.status(200).send();
});
}
};
getTags.js
module.exports = {
"post": function (req, res, next) {
// Get the notification hub used by the mobile app.
var push = req.azureMobile.push;
console.log('getting tags');
if (typeof req.body.installationId !== "undefined"){
push.getInstallation(req.body.installationId, function (error, response) {
if (error) {
console.log('An error occurred when retrieving installation\n\n' + error);
res.status(error.statusCode).send(error);
}
else {
console.log("got installation " + req.body.installationId + '\n\n' + JSON.stringify(response));
res.status(200).send(response);
}
});
}
else res.status(200).send();
}
};
main.js - here is my winjs app to create the tag and then check that it was created
client = new WindowsAzure.MobileServiceClient('https://<sitename>.azurewebsites.net');
client.invokeApi("createTags", {
body: {
installationId: client.push.installationId,
tags: ['public']
},
method: "post"
}).then(function (result) {
client.invokeApi("getTags", {
body: {
installationId: client.push.installationId,
},
method: "post"
}).then(function (result) {
WinJS.log(result);
completeDispatcher();
}, function (error) {
WinJS.log(error);
completeDispatcher();
});
}, function (error) {
WinJS.log(error);
completeDispatcher();
});
Update now trying to use this to create a channel first. Then register a listener.
// Request a push notification channel.
Windows.Networking.PushNotifications
.PushNotificationChannelManager
.createPushNotificationChannelForApplicationAsync()
.then(function (newChannel) {
channel = newChannel;
// Register for notifications using the new channel
Machine.Client.push.register('wns', channel.uri, ['public']).done(function (error, response) {
// store the channel
channel.removeEventListener("pushnotificationreceived", pushNotificationReceivedHandler);
channel.addEventListener("pushnotificationreceived", pushNotificationReceivedHandler);
completeDispatcher();
});
}, function (error) {
var dialog = new Windows.UI.Popups.MessageDialog(error, "Error");
dialog.showAsync().then(function () {
completeDispatcher();
});
});
For these type of issues, usually going through Notification Hubs Diagnosis guidelines should give you an idea where the problem is. The 'Verify registrations' section there might be helpful in your case.
If nothing there helps, could update the question with what you've learned?
I'm playing around with building a simple Facebook Messenger chatbot and I'm having trouble sending messages in sequence.
In the example above, it should have printed "Hello!", "1", "2", "3" in order. I'm currently following the Facebook docs found here to implement this simple text message function. I've included my Express Node.JS server code below:
Defining the sendTextMessage() function:
var request = require("request");
function sendTextMessage(user, text) {
messageData = {
text: text
};
request({
url: "https://graph.facebook.com/v2.6/me/messages",
qs: {access_token: PAGE_ACCESS_TOKEN},
method: "POST",
json: {
recipient: {id: user},
message: messageData
}
}, function(error, response, body) {
if (error) {
console.log("Error sending message: ", error);
} else if (response.body.error) {
console.log("Error: ", response.body.error);
} else {
console.log("Message successfully send.")
}
});
}
Using it to send a response:
sendTextMessage(user, "Hello!");
sendTextMessage(user, "1");
sendTextMessage(user, "2");
sendTextMessage(user, "3");
I even tried implementing a simple queue that queues messages and only sends one message at a time after each request's success callback. This is making me suspect that I'm not interacting with the Messenger API correctly.
Has anyone encountered this issue? How can I get messages to send in sequence? Thanks!
EDIT
Because I implemented a simple queue but still experiencing this problem, I'm including the code for my simple queue system here.
var queue = [];
var queueProcessing = false;
function queueRequest(request) {
queue.push(request);
if (queueProcessing) {
return;
}
queueProcessing = true;
processQueue();
}
function processQueue() {
if (queue.length == 0) {
queueProcessing = false;
return;
}
var currentRequest = queue.shift();
request(currentRequest, function(error, response, body) {
if (error || response.body.error) {
console.log("Error sending messages!");
}
processQueue();
});
}
queueRequest(/* Message 1 */);
queueRequest(/* Message 2 */);
queueRequest(/* Message 3 */);
UPDATE
This "bug" was reported to Facebook but it sounds like they aren't going to fix it. Please read the ticket thread on Facebook's post here for details on what they say is going on. (Thank you to Louise for getting Facebook's attention on this)
I submitted a bug report to Facebook about this because I was having the same problem. They acknowledged that it is indeed a bug and are working to fix it: https://developers.facebook.com/bugs/565416400306038
After you send a POST to /me/messages, you'll receive a response that has a message id (mine start with 'mid.' which maybe stands for message id?):
{ recipient_id: '1015411228555555',
message_id: 'mid.1464375085492:b9606c00ca33c12345' }
After being completely received by the FB Messenger API, you'll get a call to your webhook (with no message events) that confirms receipt:
{ sender: { id: '1015411228555555' },
recipient: { id: '566031806XXXXXX' },
delivery:
{ mids: [ 'mid.1464375085492:b9606c00ca33c12345' ],
watermark: 1464375085604,
seq: 176 } }
I think that delivery receipt is the best way to ensure delivery, then send the next message.
Implement the send request as a Promise and only send consequent messages once the previous one is resolved
const send = (userId, messageData) => {
return new Promise((resolve, reject) => {
request
(
{
url : BASE_URL + "me/messages",
qs : { access_token : PAGE_ACCESS_TOKEN },
method : "POST",
json :
{
recipient: { id : userId },
message: messageData,
}
}, (error, response, body) =>
{
if (error) { console.log("Error sending message: " + response.error); return reject(response.error); }
else if (response.body.error) { console.log('Response body Error: ' + response.body.error); return reject(response.body.error); }
console.log("Message sent successfully to " + userId);
return resolve(response);
}
);
});
};
You can achieve QUEUING by promises.
function delay(time) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, time);
});
}
delay(2000).then(() => {
console.log('hi');
delay(2000).then(() => {
console.log('hello');
delay(2000).then(() => {
console.log('welcome');
})
})
})
Instead of adding static timeouts, I would create a queue data structure. When the bot wants to send a message, append the contents to the end of the queue. On the message post callback, check if there are any messages still in the queue and call the function again using recursion and remove from the queue accordingly.
They should be received in the order that they are sent. Make sure you're actually sending them in order and not calling an async function 4 times (and send order isn't guaranteed). (I read that you tested it but in all my testing I've never seen a receive come out of order if the send order was guaranteed.)
I added a messageId counter to the app that resets to 0 on every start of messagehandling. Then I delay with that number * 100 ms. This way I can add intentional delays as well with code like messageDelay += 15
receivedMessage(event) {
messageDelay = 0;
//...
sendMessage extend:
function sendTextMessage(recipientId, messageText) {
//...
setTimeout(function() {
callSendAPI(messageData);
}, messageDelay++ * 100)
}
The message is not sending in order because, the request is sent asynchronously to facebook, and can be sent in any order.
To solve this you have to call the next sendTextMessage when the message that should be sent before it has received a response.
Based on the recursive solution proposed by #user3884594, I kind of make it work using this (I removed the error handling in order to simplify):
send_messages (["message 01", "message 02", "message 03"]);
function send_messages (which, i = 0)
{
request({
url: 'https://graph.facebook.com/v2.10/me/messages',
qs: { access_token: FACEBOOK_ACCESS_TOKEN },
method: 'POST',
json: { recipient: { id: senderId }, message: { text: which [i] }
}, (error, response, body) =>
{
// You need to put your error handling logic here
if (i++ < which.length - 1)
send_messages (which, i);
});
}
I had exactly same problem, that solution worked for me:
function sendMessage(recipient, messages, accessToken, i) {
axios.post(baseURL + 'v2.11/me/messages/?access_token=' + accessToken,
Object.assign({}, {
messaging_type: "RESPONSE",
recipient: {
id: recipient
}
}, messages[i]['payload']) )
.then(response => {
if(i < messages.length) sendMessage( recipient, messages, accessToken, i+1 );
},
error => {})
.catch(error => {});
}
sendMessage(recipient, flow['messages'], flow['page']['accessToken'], 0);
That's my question: Sequential Message Sending Using Facebook Send-API
You can try putting them inside a setTimeout function so each one goes after a certain period of time.
So replace this:
sendTextMessage(user, "Hello!");
sendTextMessage(user, "1");
sendTextMessage(user, "2");
sendTextMessage(user, "3");
With this:
sendTextMessage(user, "Hello!");
// 1 second
setTimeout(function() {
sendTextMessage(user, "1");
}, 1000)
// 2 seconds
setTimeout(function() {
sendTextMessage(user, "2");
}, 2000)
// 3 seconds
setTimeout(function() {
sendTextMessage(user, "3");
}, 3000)
And they should go one after another. You could also embed the functions inside each other if need be.