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

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

Related

I want to send notification push notification to android phone

I want to send notification push notification to android phone ( app build in flutter) from nodejs server.
I have registered in firebase and registered android app, downloaded google-services.json and copied to flutter application.
In firebase service account, I have generated the key and copied to nodejs server.
I have installed firebase messaging package in flutter and firebase admin in nodejs. I am receiving device token from flutter app to nodejs backend I am trying to send the message using below code.
(I dont have any user in firebase storages).
Error I am receiving is :
FirebaseMessagingError: tokens must be a non-empty array
at FirebaseMessagingError.FirebaseError [as constructor] (/usr/src/app/node_modules/firebase-admin/lib/utils/error.js:44:28)
errorInfo: {
code: 'messaging/invalid-argument',
message: 'tokens must be a non-empty array'
},
codePrefix: 'messaging'
}
var serviceAccount = require("../../config/serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
module.exports = {
sendPushNotification: (registrationToken) => {
try {
// This registration token comes from the client FCM SDKs.
var message = {
data: {
score: '850',
time: '2:45'
},
token: registrationToken
};
admin.messaging().sendMulticast(message)
.then((response) => {
console.log(response.results[0].error);
console.log(response.successCount + ' messages were sent successfully');
});
} catch (e) {
console.log(e);
}
}
}
This error occurs because you are sending an empty(null) registrationToken
You can check that by printing the registrationToken using Console.log(registrationToken)
So you have to check the method that invokes sendPushNotification and make sure that you are sending a valid token.

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??

Firebase web push notification with NodeJS not working

I'm building an app that sends web push notifications using firebase and a NodeJs server but I'm getting a 'mismatched-credential' error, how can I fix this?
I'm first generating a json file that 'generate private key' button from the console gave me , and adding the admin SDK to my app, from my server code, this way
var admin = require("firebase-admin");
var serviceAccount = require("path/to/serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://nodeproject-2bc3o.firebaseio.com"
});
Then I'm building the send request
// This registration token comes from the client FCM SDKs.
var registrationToken = 'YOUR_REGISTRATION_TOKEN';
var message = {
data: {
score: '850',
time: '2:45'
},
token: registrationToken
};
// Send a message to the device corresponding to the provided
// registration token.
admin.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);
});
The docs says that // This registration token comes from the client FCM SDKs so I'm using the token I got from the client as my registrationToken, which I retrieved the following way , from my client javascript code , and then sent to the server
messaging.getToken().then((currentToken) => {
if (currentToken) {
sendTokenToServer(currentToken);
updateUIForPushEnabled(currentToken);
}
Finally, after sending a message from the server, using the token , I get the following error
errorInfo: {
code: 'messaging/mismatched-credential',
message: 'SenderId mismatch'
},
codePrefix: 'messaging'
}
Which is the correct way to retrieve the client token , send it to the server , and then use it to send a push notification to the client? Or what I'm I doing wrong?
If you use Firebase Cloud Functions as backend server then the serviceAccountKey.json is not necessary and more simple.
See https://firebase.google.com/docs/functions/get-started#import-the-required-modules-and-initialize-an-app
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access Cloud Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
These lines load the firebase-functions and firebase-admin modules, and initialize an admin app instance from which Cloud Firestore changes can be made.
And, fcm sample is https://github.com/firebase/functions-samples/tree/master/fcm-notifications

How to send a notification to device using firebase admin

I am adding notification support to an app. I'm using react native firebase for the react native client and am able to receive notification sent by the console.
However, when I send the notification using the firebase admin tool no notification is received.
firebase admin is initialised once on server startup
let admin = require('firebase-admin')
let serviceAccount = require('../../appname-firebase-admin.json')
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://appname-12e14.firebaseio.com',
})
console.log('initialise firebase admin')
and then I've made this test function based on the firebase admin documentation
async function sendNotification() {
let admin = require('firebase-admin')
let registrationToken =
'super-long-token-goes-here'
let message = {
notification: { title: 'Super title', body: 'this is a test' },
token: registrationToken,
}
admin
.messaging()
.send(message)
.then(response => {
// Response is a message ID string.
console.log('Successfully sent notification:', response)
return { success: true }
})
.catch(error => {
console.log('Error sending notification:', error)
})
return {
success: true,
}
}
this results in
Successfully sent notification: projects/appname-12e14/messages/0:1574700947563522%48f1ba652348f1ba99
with no notification on the device.
edit: I've also tried using .sendToDevice()
React-native-firebase does display the notifications in an open app, you can create a custom notification and use the component you like to show it in app. Alternatively you can use a third-party service like Notify, which has a simple API to manage them.

Resources