Firebase Cloud Messaging: event is not defined - javascript

I've got a problem with Firebase Cloud Messaging notifications. When I want to send friend request the other client doesn't receive a notification. And Firebase Functions log says:
ReferenceError: event is not defined
at exports.sendNotification.functions.database.ref.onWrite (/user_code/index.js:14:8)
at cloudFunctionNewSignature (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:109:23)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:139:20)
at /var/tmp/worker/worker.js:728:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
Here is JavaScript code:
'use strict'
const functions = require('firebase-functions');
const admin = require ('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/Notifications/{receiver_id}/{notification_id}').onWrite((change,context) => {
const receiver_id = context.params.receiver_id;
const notification_id = context.params.notification_id;
console.log('We have a notification to send to: ', receiver_id);
if (!event.data.val) {
return console.log('A notification has been deleted from database: ', notification_id);
}
const deviceToken = admin.database().ref(`/Users/${receiver_id}/device_token`).once('value');
return deviceToken.then(result => {
const token_id = result.val();
const payload = {
notification:
{
title: "Friend Request",
body: "you have received a new friend request",
icon: "default"
}
};
return admin.messaging().sendToDevice(token_id, payload).then(response => {
console.log('This was the notification feature.');
});
});
});

Change this:
if (!event.data.val) {
return console.log('A notification has been deleted from database: ', notification_id);
}
into this:
if (!change.after.val()) {
return console.log('A notification has been deleted from database: ', notification_id);
}
The change object has two properties after and before, each of these is a DataSnapshot with the same methods available in admin.database.DataSnapshot.
Also val() is a method not a property.

Related

firebase cloud functions for push notifications are not working

in my flutter app, i have saved every devices token to a collection in firebase database and i wrote the code for firebase cloud functions so it sends a message(notification) for every user that subscribed to a topic and have their token is in the tokens collection but it doesnt send anything when i add something to the topic i subscribed them to, heres my cloud functions code using javascrpit in the index file:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().functions);
var newData;
exports.myTrigger = functions.firestore.document('messages/{messageId}').onCreate(async (snapshot, context) => {
//
if (snapshot.empty) {
console.log('No Devices');
return;
}
newData = snapshot.data();
const deviceIdTokens = await admin
.firestore()
.collection('messages')
.get();
var tokens = [];
for (var tokened of deviceIdTokens.docs) {
tokens.push(tokened.data().token);
}
var payload = {
notification: {
title: 'Push Title',
body: 'Push Body',
sound: 'default',
},
data: {
message: newData.message,
click_action: 'FLUTTER_NOTIFICATION_CLICK',
},
};
try {
const response = await admin.messaging().sendToDevice(tokens, payload);
console.log('Notification sent successfully');
} catch (err) {
console.log(err);
}
});
and heres my database structure
and the tokens collection :
what am i doing wrong?
trying his instead :
i should have written :
'''
const deviceIdTokens = await admin
.firestore()
.collection('tokens')
.get()
'''
also for sending a message through the database i should have written "message" in the field because i named the "data"'s key "message" :)

Push Notification from Firestore

I need to send notification when data change in my Cloud Firestore database. I have this fields
I need to get the all users tokens and send the push notification. I have a code, but this only give me a token if i know the user name this is my code :
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.useWildcard = functions.firestore
.document('notification/{id}')
.onWrite((change, context) => {
const payload = {
notification: {
title: 'Message from Cloud',
body: 'This is your body',
badge: '1',
sound: 'default'
}
};
admin.firestore().collection('notification').doc('fcm-token').get().then(doc => {
console.log("Token: " + doc.data().user1.token);
});
});
To loop over all users in the document:
admin.firestore().collection('notification').doc('fcm-token').get().then(doc => {
let data = doc.data();
Object.keys(data).forEach((user) {
console.log("Token: " + data[user].token);
});
});
But as Doug commented: storing the tokens for all users in a single document is bound to become a scalability problem at some point.

JavaScript Firebase Notifications Error Error: Registration token(s) provided to sendToDevice() must be a non-empty string or a non-empty array

I keep getting this error for few days on notifications part of my andriod project. The version of firebase tools that I use currently in npm is 3.9.1 not being the latest due to some issues.
Error
Error: Registration token(s) provided to sendToDevice() must be a
non-empty string or a non-empty array.
at FirebaseMessagingError.Error (native)
at FirebaseMessagingError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:25:28)
at new FirebaseMessagingError (/user_code/node_modules/firebase-admin/lib/utils/error.js:130:23)
at Messaging.validateRegistrationTokensType (/user_code/node_modules/firebase-admin/lib/messaging/messaging.js:576:19)
at Messaging.sendToDevice (/user_code/node_modules/firebase-admin/lib/messaging/messaging.js:197:14)
at deviceToken.then.result (/user_code/index.js:36:32)
at process._tickDomainCallback (internal/process/next_tick.js:135:7
CODE FROM HERE
'use strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/notifications/{user_id}/{notification_id}').onWrite(event => {
const user_id = event.params.user_id;
const notification_id = event.params.notification_id;
console.log('We have a notification from : ', user_id);
if(!event.data.val()){
return console.log('A Notification has been deleted from the database : ', notification_id);
}
const deviceToken = admin.database().ref(`/Users/${user_id}/device_token`).once('value');
return deviceToken.then(result => {
const token_id = result.val();
const payload = {
notification: {
title : "New Friend Request",
body: "Firend Request has sent you request",
icon: "default"
}
};
return admin.messaging().sendToDevice(token_id, payload).then(response => {
console.log('This was the notification Feature');
});
});
});

Unable to send notifications using firebase functions after update

So Today I updated the firebase cli and after that deployed a new function. Although the firebase log shows that notifications has been sent to this many tokens, no notification occurs. An error shows in the log
Function returned undefined, expected Promise or value
I searched for answers in stack overflow but nothing helped.
Also I would like to add that before it was showing some different error
TypeError: Cannot read property 'description' of null
and now suddenly it is showing function returned undefined.
Not sure what is wrong. Any help is appreciated.
Index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
function token_send(admin,title_input,body_input,getBody,getDeviceTokensPromise,change){
// Only edit data when it is first created.
if (change.before.val()) {
return 0;
}
// Exit when the data is deleted.
if (!change.after.val()) {
return 0;
}
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.');
var contentAlert = change.after.val();
// Notification details.
const payload = {
'data': {
'title': title_input,
'body': body_input
}
};
const tokens = Object.keys(tokensSnapshot.val());
// Send notifications to all tokens.
return admin.messaging().sendToDevice(tokens, payload).then(response => {
console.log("Successfully sent message:", response);
console.log("content alert",contentAlert);
// 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);
});
});
}
exports.sendNotificationCouncil = functions.database.ref(`path/Post/{pushId}`).onWrite((change,context) => {
const getDeviceTokensPromise = admin.database().ref(`/Token/token_no`).once('value');
const getBody=admin.database().ref(`/Post`).once('value');
var title_input='You have new Post';
var contentAlert = change.after.val();
var body_input=contentAlert.description; //showing error here
token_send(admin,title_input,body_input,getBody,getDeviceTokensPromise,change);
});
You should return the promise (returned by token_send()) in the sendNotificationCouncil Cloud Function, as follows:
exports.sendNotificationCouncil = functions.database.ref(`path/Post/{pushId}`).onWrite((change,context) => {
const getDeviceTokensPromise = admin.database().ref(`/Token/token_no`).once('value');
const getBody=admin.database().ref(`/Post`).once('value');
var title_input='You have new Post';
var contentAlert = change.after.val();
var body_input=contentAlert.description; //showing error here
return token_send(admin,title_input,body_input,getBody,getDeviceTokensPromise,change);
});
Note that it is also a best practice to catch the errors in your Function and in this case return false.

Cloud Functions for Firebase and FCM

I recently developed an application for a school and one of its features is principal's updates. For this, I'm using the Firebase database for this (on Android studio and Xcode). I heard that there is a new Firebase feature that calls cloud functions and I heard that I can integrate Database and FCM. For now, I have this code in index.js:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
// response.send("Hello from Firebase!");
// });
exports.sendNotifications = functions.database.ref('/messageS/{id}').onWrite(event => {
const snapshot = event.data;
// Only send a notification when a message has been created.
if (snapshot.previous.val()) {
return;
}
// Notification details.
const text = snapshot.val().text;
const payload = {
notification: {
title: 'new message recived',
body: text ? (text.length <= 100 ? text : text.substring(0, 97) + '...') : '',
icon: '/app/src/main/res/drawable/logo_he_digita_homepage.png'
}
};
// Get the list of device tokens.
return admin.database().ref('fcmTokens').once('value').then(allTokens => {
if (allTokens.val()) {
// Listing all tokens.
const tokens = Object.keys(allTokens.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(allTokens.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
});
}
});
});
I receive the log into Firebase console, but I don't see fcmTokens in the database and the device doesn't get the notification. what should I do?
Thanks for the help.

Categories

Resources