TypeError: Vonage is not a constructor - vonage

I'm trying to send an SMS message to a random phone number from a node js file. I'm using my Vonage account. When I try this from the web page of the Vonage (https://dashboard.nexmo.com/getting-started/sms), it works perfectly. But when I run the code they suggest, it doesn't work anymore and I get this error: TypeError: Vonage is not a constructor+
After I installed the package (npm install #vonage/server-sdk), I created a js file with this code:
const Vonage = require('#vonage/server-sdk')
const vonage = new Vonage({
apiKey: "27945288",
apiSecret: "************Ek95"
})
const from = "Vonage APIs"
const to = "*********13"
const text = 'A text message sent using the Vonage SMS API'
async function sendSMS() {
await vonage.sms.send({to, from, text})
.then(resp => { console.log('Message sent successfully'); console.log(resp); })
.catch(err => { console.log('There was an error sending the messages.'); console.error(err); });
}
sendSMS();
I run it with: "node sendSMS.js"

The Vonage variable is not a constructor function, which is required to create a new instance of the class, as indicated by the error message "TypeError: Vonage is not a constructor."
It appears that you are attempting to utilize the deprecated and no longer maintained package #vonage/server-sdk.
Instead, you can use the package vonage and execute it as follows:
Also, make sure that you have the correct API Key and API Secret from your account on the https://dashboard.vonage.com/
And also, you need to replace the phone number with the actual number you want to send the message to.
const vonage = require('vonage');
const client = new vonage.Client({
apiKey: "your_api_key",
apiSecret: "your_api_secret"
});
const from = "Vonage APIs"
const to = "*********13"
const text = 'A text message sent using the Vonage SMS API'
async function sendSMS() {
await client.sms.send({to, from, text})
.then(resp => { console.log('Message sent successfully'); console.log(resp); })
.catch(err => { console.log('There was an error sending the messages.'); console.error(err); });
}
sendSMS();
Additionally, confirm that you are using the appropriate API Key and API Secret from your Dashboard at https://dashboard.vonage.com account.
Additionally, you must substitute the phone number with the one you wish to really send the message to.

Related

I have this node.js cloud function but it does not work?

I have this cloud function using node.js that listen every time a child is added on a specific node, then it sends a notification to the users. However when I added something on the database, it does not send anything. I am working on android studio java. Should I connect the function to the android studio, if it will only listen on the database and then send FCM messages on the device tokens.
also how to do debugging on this, I am using VS code.
This is my code:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.listen = functions.database.ref("/Emergencies/{pushId}")
.onCreate(async (change, context) => {
change.after.val();
context.params.pushId;
// Get the list of device notification tokens. Note: There are more than 1 users in here
const getDeviceTokensPromise = admin.database()
.ref("/Registered Admins/{uid}/Token").once("value");
// The snapshot to the user's tokens.
let tokensSnapshot;
// The array containing all the user's tokens.
let tokens;
const results = await Promise.all([getDeviceTokensPromise]);
tokensSnapshot = results[0];
// Check if there are any device tokens.
if (!tokensSnapshot.hasChildren()) {
return functions.logger.log(
'There are no notification tokens to send to.'
);
}
functions.logger.log(
'There are',
tokensSnapshot.numChildren(),
'tokens to send notifications to.'
);
// Notification details.
const payload = {
notification: {
title: "New Emergency Request!",
body: "Someone needs help check Emergenie App now!",
}
};
// Listing all tokens as an array.
tokens = Object.keys(tokensSnapshot.val());
// Send notifications to all tokens.
const response = await admin.messaging().sendToDevice(tokens, payload);
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
functions.logger.error(
'Failure sending notification to',
tokens[index],
error
);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
});
This seems wring:
const getDeviceTokensPromise = admin.database()
.ref("/Registered Admins/{uid}/Token").once("value");
The {uid} in this string is not defined anywhere, and is also going to be treated as just a string, rather than the ID of a user - which is what I expect you want.
More likely, you'll need to:
Load all of /Registered Admins
Loop over the results you get from that
Get the Token value for each of them
If you are new to JavaScript, Cloud Functions for Firebase is not the easiest way to learn it. I recommend first using the Admin SDK in a local Node.js process or with the emulator suite, which can be debugged with a local debugger. After those you'll be much better equipped to port that code to your Cloud Functions.

How to Authenticate a Service Account for the Gmail API in Node Js?

So I'm using the Node.js Gmail library to send an email to another user. I was thinking of using a Service account to do just that. I've followed their documentation of passing the keyFile property but when I try to run the code, I get a 401 error, Login Required.
Here's what I got so far:
const { gmail } = require("#googleapis/gmail");
function createMessage(from, to, subject, message) {
// logic that returns base64 email
const encodedMail=[...];
return encodedMail;
}
export default function handler(req, res) {
const auth = gmail({
version: "v1",
keyFile: './google_service.json',
scopes: ["https://www.googleapis.com/auth/gmail.send"],
});
const raw = createMessage(
process.env.SERVICE_EMAIL,
"someone#gmail.com",
"Subject",
"This is a test",
);
const post = auth.users.messages.send({
userId: "me",
requestBody: {
raw,
},
});
post
.then((result) => {
console.log(result.data);
})
.catch((err) => {
console.log(err);
});
}
I've already got my Service Account credential json file and placed it at the root of my project. Is there something I'm doing wrong?

is it possible to send push notification to only active clients using firebase cloud messaging and node.js server

I want to know wether it is possible to send push notification using firebase cloud messaging and node.js server? How can I do this?
Yes, It is possible using either API endpoints provided by firebase or by using firebase-admin npm package.
Minimal Example -
const firebaseAdmin = require('firebase-admin')
if (!firebaseAdmin.apps.length) {
firebaseAdmin.initializeApp({
credential: firebaseAdmin.credential.cert(serviceAccountJson),
databaseURL: databaseUrl
})
}
// This registration token comes from the client FCM SDKs.
const registrationToken = 'YOUR_REGISTRATION_TOKEN';
const message = {
data: {
score: '850',
time: '2:45'
},
token: registrationToken
};
// Send a message to the device corresponding to the provided
// registration token.
firebaseAdmin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
For further documentation please refer to -
https://firebase.google.com/docs/cloud-messaging/send-message

Why message id from Firebase Cloud Messaging is empty

I am migrating from legacy HTTP to v1 using the NPM firebase-admin module. But I have the problem that when sending the notification it doesn't give any error, but it doesn't return the message-id and the notification is not received on the device.
Node version: 12.14.1.
firebase-admin version: 9.6.0
Server code:
const admin = require('firebase-admin');
var serviceAccount = require('./file.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
const messaging = admin.messaging();
async function sendPush() {
const message2 = {
notification: {
title: 'test title',
body: 'test'
},
token: 'valid-token'
};
try {
const test = await messaging.send(message2);
console.log('--------------------------Successfully sent message:--------------------------');
console.log(test);
console.log('------------------------------------------------------------------------------');
} catch(err) {
// Will catch both thrown exceptions as well as rejections
console.log('--------------------------Error sending message:', err);
}
}
When I send a notification using the sendPush function, I receive the following response in the console:
--------------------------Successfully sent message:--------------------------
projects/project-name/messages/
------------------------------------------------------------------------------
It does not contain the message-id specified in the docs and I am not receiving the notification.
Docs sample response:
projects/myproject-b5ae1/messages/0:1500415314455276%31bd1c9631bd1c96
Edit:
I tested the sendToDevice function (Legacy API) from firebase-admin and it works.
messaging.sendToDevice('valid-token', message)
.then(response => {
console.log('--------------------------Successfully sent message:--------------------------');
console.log(response);
console.log('------------------------------------------------------------------------------');
})
.catch(err => {
console.log('--------------------------Error sending message:', err);
});
The push is delivered. But send, sendMulticast and sendAll (v1 API) still not working.
Solved.
The problem was that the token coming from android was not correct for the new FCM versions. After updating the token generation in the apps, it has started to work with both legacy and v1.

credentials used to authenticate does not have permission

I am trying to use firebase cloud messaging to deploy a http push notifications onto an actual device. When so, I am getting the error
"The credential used to authenticate this SDK does not have permission to send messages to the device corresponding to the provided registration token. Make sure the credential and registration token both belong to the same Firebase project."
I have checked the credentials on both the frontEnd and backEnd side and they all match up with my firebase correctly. I have tried to follow plenty of examples on here and I have missed on all of them. My node.js file looks like
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
export GOOGLE_APPLICATION_CREDENTIALS = "/Users/myname/mylocation/myfile.json"
exports.sendPushNotifications = functions.https.onRequest((req, res) => {
res.send("Attempting to send push notification")
console.log("LOGGER --- Trying to send push message..");
var uid = 'randomUIDString'
var fcmToken = 'myToken'
return admin.database().ref('/users/' + uid).once('value', snapshot => {
var user = snapshot.val();
console.log("username is " + user.name);
var payload = {
notification: {
title: 'Push Notification Title',
body: 'Test Notification Message'
}
}
admin.messaging().sendToDevice(fcmToken, payload)
.then(function(response) {
console.log('Succesfully sent message:', response);
console.log(response.results[0].error);
})
.catch(function(error) {
console.log('Error sending message', error);
});
})
})
The users name prints from calling the uid, but I am having trouble accessing the fcmToken.
I have checked my info.plist and the correct project is listed. Same with apple developer and appDelegate. is there something more that I am missing??

Resources