Node.js/Firebase: Notifications won't reach device - node.js

A few months ago i started using Firebase's backend tools. they're awesome. So i had to move our current method of notifying users of their to-do list. We moved to Cloud Functions and it was 40x faster. Until a week ago i got a fresh copy of MacOS i had to delete everything in my Solid State Drive. When i did i also installed the firebase command line tools. I had my code which i used to notify users, it suddenly stopped working
Here's what happens:
When someone adds a new record to our daily list. the app notifies other family members about the new record. So i had to come up with a method to do so..
OLD CODE (worked seamlessly)
const functions = require('firebase-functions');
var admin = require("firebase-admin");
admin.initializeApp();
var registrationToken = 'egV-C3ItwJE:APA91bGf5ezSRQQFHkzCNzfqhS6tiKRbs6IXXs57DFTrNCWRrVY0pZ4PHsK8G3ZjvvvO4JCvd13j_jBcJkgRh06YJ5Jw6tohc81Ro0k4HdHG-Jlv4sbW5t1DNmJBDeGf48l05eDlfMGO';
var payload = {
data: {
title: 'TEST/2',
body: 'TEST/2'
}
};
// registration token.
admin.messaging().sendToDevice(registrationToken, payload)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response, payload);
return
})
.catch((error) => {
console.log('Error sending message:', error);
});
Back in my previous version of macOS this code had no issues. upgrading Firebase Command Line tools i had to make some edits to the code:
NEW CODE (NOT WORKING)
// This registration token comes from the client FCM SDKs.
var registrationToken = 'egV-C3ItwJE:APA91bGf5ezSRQQFHkzCNzfqhS6tiKRbs6IXXs57DFTrNCWRrVY0pZ4PHsK8G3ZjvvvO4JCvd13j_jBcJkgRh06YJ5Jw6tohc81Ro0k4HdHG-Jlv4sbW5t1DNmJBDeGf48l05eDlfMGO';
// See documentation on defining a message payload.
var message = {
data: {
title: '850',
body: '2:45'
},
token: registrationToken
};
// Don't use the legacy sendToDevice
admin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
return
})
.catch((error) => {
console.log('Error sending message:', error);
});
The Problem is:
1- When this function hits. i get the "Successfully sent message:" response. but the message won't reach the device
Things i have tried:
1- The device token is correct and i have tested it using the manual push notification on single devices
2- The device receives notifications.
3- The device runs on iOS 11.1 same as before
Thanks

Can u check with this function,I had tried with this I am able to get notifications.
In you first code sample u had user sendToDevice but in second sample you had used send
function sendPushNotification(fcmtoken, notificationTitle, notificationMessage) {
if (fcmtoken != null && fcmtoken != "" && fcmtoken != " ") {
var payload = {
notification: {
title: notificationTitle,
body: notificationMessage,
sound: "default"
}
};
admin.messaging().sendToDevice(fcmtoken, payload)
.then(function (response) {
}).catch(function (error) {
console.log("Error sending message:", error);
});
}
}

Related

Error occured Invalid payload provided. No JSON object could be decoded Coinbas

I having been battling this error for weeks now, read hundreds of resources that has just proven futtile and contacted coinbase support without getting any response from them. When I try testing the webhook from the coinbase Api I get this error "Remote server at 07b0a16c5735.ngrok.io returned an HTTP 400" and in my console I get "Error occured Invalid payload provided. No JSON object could be decoded"
I have attached screenshots of the errors I am encountering and this my code for the endpoint;
app.post(
"/endpoint", (request, response) => {
var event;
console.log(request.headers);
try {
event = Webhook.verifyEventBody(
request.rawBody,
request.headers["x-cc-webhook-signature"],
webhookSecret
);
} catch (error) {
console.log("Error occured", error.message);
return response.status(400).send("Webhook Error:" + error.message);
}
console.log("Success", event.id);
console.log(request.rawBody);
response.status(200).send("Signed Webhook Received: " + event.id);
}
);
I am currently using this line of code to parse the raw body to json:
function rawBody(req, res, next) {
req.setEncoding("utf8");
var data = "";
req.on("data", function (chunk) {
data += chunk;
});
req.on("end", function () {
req.rawBody = data;
next();
});
}
app.use(rawBody);
I tried using express.json() but supplemented it for the above line code when I was still getting the same error. This is the response I am expecting:
Success 00000000-0000-0000-0000-000000000000
{"id":"00000000-0000-0000-0000-000000000000","scheduled_for":"2018-01-01T00:40:00Z","attempt_number":1,"event":{"id":"00000000-0000-0000-0000-000000000000","resource":"event","type":"charge:confirmed","api_version":"2018-03-22","created_at":"2018-01-01T00:40:00Z","data":{"code":"AAAAAAAA","id":"00000000-0000-0000-0000-000000000000","resource":"charge","name":"The Sovereign Individual","description":"Mastering the Transition to the Information Age","hosted_url":"https://commerce.coinbase.com/charges/AAAAAAAA","created_at":"2018-01-01T00:00:00Z","confirmed_at":"2018-01-01T00:40:00Z","expires_at":"2018-01-01T01:00:00Z","support_email":"test#test.test","timeline":[{"time":"2018-01-01T00:00:00Z","status":"NEW"},{"status":"PENDING","payment":{"network":"ethereum","transaction_id":"0x0000000000000000000000000000000000000000000000000000000000000000"},"time":"2018-01-01T00:30:00Z"},{"status":"COMPLETED","payment":{"network":"ethereum","transaction_id":"0x0000000000000000000000000000000000000000000000000000000000000000"},"time":"2018-01-01T00:40:00Z"}],"metadata":{},"payment_threshold":{"overpayment_absolute_threshold":{"amount":"15.00","currency":"USD"},"overpayment_relative_threshold":"0.1","underpayment_absolute_threshold":{"amount":"5.00","currency":"USD"},"underpayment_relative_threshold":"0.1"},"pricing":{"local":{"amount":"100.00","currency":"USD"},"bitcoin":{"amount":"1.00000000","currency":"BTC"},"usdc":{"amount":"10.000000","currency":"USDC"},"bitcoincash":{"amount":"5.00000000","currency":"BCH"},"litecoin":{"amount":"2.00000000","currency":"LTC"}},"pricing_type":"fixed_price","payments":[{"network":"ethereum","transaction_id":"0x0000000000000000000000000000000000000000000000000000000000000000","status":"CONFIRMED","detected_at":"2018-01-01T00:30:00Z","value":{"local":{"amount":"100.0","currency":"USD"},"crypto":{"amount":"10.00","currency":"ETH"}},"block":{"height":100,"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","confirmations_accumulated":8,"confirmations_required":2}}],"addresses":{"bitcoin":"1000000000000000000000000000000000","usdc":"0x0000000000000000000000000000000000000000","litecoin":"3000000000000000000000000000000000","bitcoincash":"bitcoincash:000000000000000000000000000000000000000000"},"exchange_rates":{"BCH-USD":"1000.0","BTC-USD":"100.0","ETH-USD":"10.0","JPY-USD":"0.5","LTC-USD":"50.0","TST-USD":"0.5","BEER-USD":"0.1"}}}}
I had the same issue.
What worked for me was downgrading the version of the npm package that handles the payload within the webhook (coinbase-commerce-node) to the version 1.0.0.
I also implemented the webhook exactly as shown in the examples of the library:
https://github.com/coinbase/coinbase-commerce-node/tree/master/examples/webhook
You also need to make sure your server is properly configured to work with SSL. For example if you have the webhook implemented in Heroku, you can use heroku-ssl-redirect to force the usage of SSL.
Instead of sending the rawBody, you can use stringify object to verify the signature.
app.use(bodyParser.json());
try {
const event = Webhook.verifyEventBody(JSON.stringify(req.body), signature, webhookSecret);
if (event.type === 'charge:pending') {
// TODO
// user paid, but transaction not confirm on blockchain yet
}
if (event.type === 'charge:confirmed') {
// TODO
// all good, charge confirmed
}
if (event.type === 'charge:failed') {
// TODO
// charge failed or expired
}
res.send(`success ${event.id}`);
} catch (error) {
if (error) {
console.log(error);
}
res.status(400).send('failure!');
}

Azure Notification Hub Exception : not able to register device entries.. the request could not be completed

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.

Twilio programmable SMS not sending in deployed Lambda function

I am working on a Serverless AWS service that uses Twilio's programmable SMS to deliver text messages.
My setup is consistently delivering messages successfully when I run the stack locally (e.g. sls offline start), but in the deployed environment I seem to be unable to even call the method on the Twilio client.
Here's how the message delivery is set up:
const twilio = require('twilio');
const twilioClient = twilio(
process.env.TWILIO_SID,
process.env.TWILIO_TOKEN,
{
lazyLoading: true,
}
);
export function sendMessage(user, message) {
twilioClient.messages.create({
from: process.env.TWILIO_NUMBER,
to: user.phone,
body: message,
}, function(err, message) {
console.log('error', err);
console.log('message', message);
});
}
// And then usage in a Serverless Function Handler
function example(event, context, callback) {
context.callbackWaitsForEmptyEventLoop = false;
// user is also determined here
sendMessage(user, 'This is a message');
return {
body: JSON.stringify({}),
statusCode: 200
};
}
Locally, running this works and I am able to see the output of the message log, with nothing on the error log. However, when deployed, running this yields nothing -- the method appears to not even get called (and I can verify in the Twilio logs that no API call was made), therefor no error or message logs are made in the callback.
In debugging I've tried the following:
I've logged all the environment variables (Twilio SSID, auth token, phone number), as well as the function arguments, and they all appear to be in place. I also checked out the Lambda function itself to make sure the environment variables exist.
I've examined my CloudWatch logs; no errors or exceptions are logged. Other than the Twilio method not getting called the Lambda function is executed without issue.
I've tried logging things like twilio and twilioClient.messages.create to make sure the client and function definition didn't get wiped out somehow.
I thought maybe it had to do with context.callbackWaitsForEmptyEventLoop so I changing it from false to true.
I have come up empty, I can't figure out why this would be working locally, but not when deployed.
Edit: per the Twilio client example, if you omit the callback function the method will return a Promise. I went ahead and tried to await the response of the method:
export function sendMessage(user, message) {
return twilioClient.messages.create({
from: process.env.TWILIO_NUMBER!,
to: user.phone,
body: message,
});
}
// Usage...
async function example(event, context, callback) {
context.callbackWaitsForEmptyEventLoop = false;
try {
const message = await sendMessage(user, 'This is a message');
console.log('message', message)
} catch (error) {
console.log('error', error);
}
return {
body: JSON.stringify({}),
statusCode: 200
};
}
In this example the Lambda function is successful, but neither the message nor the error are logged.
I tried this and it works. I tried to make my code as similar to use, with a few changes.
const twilio = require('twilio');
const twilioClient = twilio(
process.env.TWILIO_SID,
process.env.TWILIO_TOKEN
);
let user = '+14075551212';
function sendMessage(user, message) {
return twilioClient.messages.create({
from: process.env.TWILIO_NUMBER,
to: user,
body: message,
});
}
exports.handler = async function(event, context, callback) {
try {
const message = await sendMessage(user, 'This is a message');
console.log('message', message);
callback(null, {result: 'success'});
} catch (error) {
console.log('error', error);
callback("error");
}
};

Get the Message notification from Nodejs REST API using Angular8 in background

I am working on an application where I want to implement the message Inbox. I have created the message inbox using Angular8 and NodeJS REST API. Now I want to get the on inbox message in every 30 Second on the background when user login also it doesn't want to affecting the performance of the Angular app.
So I want to Implement the Web-worker with Angular8 to get the Data from NodeJS REST API but I am unable to create.
I have added following code in Angular 8 App
Add this code to app.component.ts
getWorker(token){
if (typeof Worker !== 'undefined') {
// Create a new
const worker = new Worker('../../web-worker/messenger.worker', { type: `module` });
worker.postMessage(token);
worker.onmessage = (e) => {
setTimeout(() => {
worker.postMessage(token)
}, 15000);
};
} else {
// Web Workers are not supported in this environment.
// You should add a fallback so that your program still executes correctly.
}
}
Created worker file with fetch
/// <reference lib="webworker" />
addEventListener('message', ({ data }) => {
const response = `worker response to ${data}`;
postMessage(response);
});
import { environment } from "src/environments/environment";
onmessage = (message:any) => {
fetch(environment.apiUrl +'messages/notification/1/1',
{ method:'GET',
headers:new Headers({
Authorization: `Bearer ${message.data}`
})
}
)
.then(response => {
return response.json()
})
.then(commits => {
// self.onmessage(message)
return commits
});
};
but it shows the type as fetch is should be show web worker Right?
Can anyone help me with this?

Nodejs Firebase reference to database keeps on checking value

I tried creating one program which fetch data from firebase database from node js server.
function FCM()
{
var payload = {
data: {
//Some data
}
};
var db = admin.database();
var ref = db.ref("PATH_TO_DATABASE");
ref.on("value", function(snapshot) {
registrationToken = REGISTRATION TOKEN
admin.messaging().sendToDevice(registrationToken, payload)
.then(function(response) {
console.log("Successfully sent message:", response);
})
.catch(function(error) {
console.log("Error sending message:", error);
});
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}
But when this function gets completed then the server keeps on running as usual which is fine but the problem is that when any data gets deleted from PATH_TO_DATABASE then it gives error:
TypeError: Cannot convert undefined or null to object
Now I don't want firebase to keep on checking the value to that path. I just want to free that thing. So how I can do it ?
ref.on("value") is going to trigger whenever that value changes, like when the data is deleted. Instead use
ref.once("value", function(snapshot)
Then admin.messaging().sendToDevice(registrationToken, payload) won't get triggered again.

Resources