Reputation: 183
I am using firebase cloud functions for sending notifications to users when database trigger is called.The registration token is saved in firebase database. The problem is that inspite of registration tokens getting saved, the notifications are not showing up in these devices. This is index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/Blog').onWrite(event => {
const title = event.data.child('title').val();
const token_no = event.data.child('token_no').val();
const getDeviceTokensPromise = admin.database().ref(`/Token/${token_no}`).once('value');
const getBody=admin.database().ref(`/Blog`).once('value');
return Promise.all([getDeviceTokensPromise,getBody]).then(results => {
const tokensSnapshot = results[0];
const notify=results[1];
if (!tokensSnapshot.hasChildren()) {
return console.log('There are no notification tokens to send to.');
}
console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');
// Notification details.
const payload = {
notification: {
title: 'You have a new Alert!',
body: `${notify.child('title').val()}`,
}
};
// Listing all tokens.
const tokens = Object.keys(tokensSnapshot.val());
// Send notifications to all tokens.
return admin.messaging().sendToDevice(tokens, payload).then(response => {
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
console.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);
});
});
});
Database snapshot:
"Token" : {
"token_no" : {
"ctxjePemYZE:APA91bFJXXyTkyvXOlSY...4VbWu7Vbf7itwbwZu9umSvg_tdB1lKD1d8g" : "true",
"dgVszInjIW0:APA91bFZE3Av5unZTgp...RUeYb-CUhWjO1otqguhE9NTQZ8XgK6nRIW5" : "true"
}
}
Upvotes: 0
Views: 236
Reputation: 38309
Update 2:
Your code uses Object.keys(tokensSnapshot.val())
to get the tokens. That means the tokens must be the keys under token_no
, not the values. Like this:
"Token" : {
"-KoWsMn9rCIitQeNvixr" : {
"dK1FjGbNr6k:APA91b...S8JK2d69JpO" : "123" // token is the key, value is not significant; could be "123", true, or 0.
},
...
}
Update:
You should review the documentation for the Event parameter of a database trigger to get a better understanding of the params
and data
properties. params
provide acces to the wildcards in the trigger reference, data
is the snapshot. In your code, you want to get values from the snapshot.
Add these changes:
const title = event.data.child('title').val();
const desp = event.data.child('desp').val();
const token_no = event.data.child('token_no').val()
const payload = {
notification: {
title: 'You have a new Alert!',
body: `${Post.child('title').val()}`, // <= CHANGED
//icon: follower.photoURL
}
};
Running the code you posted, with these changes, I am able to send and receive a notification.
There are two problems. The first is this statement:
const getDeviceTokensPromise = admin.database().ref(`/Token/{token_no}`).once('value');
token_no
is not defined. And when you do define it and want to substitute its value, you will need to add a $
:
`/Token/${token_no}`
The second problem is that Post
is not defined, which causes function execution to fail. Check your function logs:
const payload = {
notification: {
title: 'You have a new Alert!',
body: `${Post.title}`,
//icon: follower.photoURL
}
};
Upvotes: 1