firebase cloud function snapshot undefined - javascript

Im trying to write a function with firebase cloud function which will send an email as soon as a new message is added to my "contactMessages" realtime database. so i did this but here i got an undefined snapshot :
const functions = require("firebase-functions");
const nodemailer = require("nodemailer");
const gmailEmail =
encodeURIComponent(functions.config().gmail.email);
const gmailPassword =
encodeURIComponent(functions.config().gmail.password);
const mailTransport = nodemailer.createTransport(
`smtps://${gmailEmail}:${gmailPassword}#smtp.gmail.com`
);
exports.sendContactMessage = functions.database
.ref("/contactMessages/{pushKey}")
.onWrite((change, context) => {
// Only send email for new messages.
if (snapshot.previous.val() || !snapshot.val().name) {
return;
}
const val = snapshot.val();
const mailOptions = {
to: "test#example.com",
subject: `Information Request from ${val.name}`,
html: val.html
};
return mailTransport.sendMail(mailOptions).then(() => {
return console.log("Mail sent to: test#example.com");
});
});

Change this:
exports.sendContactMessage = functions.database
.ref("/contactMessages/{pushKey}")
.onWrite((change, context) => {
// Only send email for new messages.
if (snapshot.previous.val() || !snapshot.val().name) {
return;
}
into this:
exports.sendContactMessage = functions.database
.ref("/contactMessages/{pushKey}")
.onWrite((change, context) => {
// Only send email for new messages.
if (change.before.val() || !change.after.val().name) {
return;
}
From the docs:
For onWrite and onUpdate events, the change parameter has before and after fields. Each of these is a DataSnapshot with the same methods available in admin.database.DataSnapshot.

Related

How can i send different type of Notificaton with FirebaseCloud sendNotification Function

I have this function which sends notification once there is certain change in my Db node. but i want to send multiple type of notifications for different actions. but when i deploy my function it overrides prior one and then i have tried all functions in single script but its not working properly
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/All_Users/{reciever_user_id}/CouponsUsedNotifications/{notification_id}')
.onWrite((data, context ) => {
const reciever_user_id = context.params.reciever_user_id;
const notification_id = context.params.notification_id;
console.log('Notification sent to : ', reciever_user_id)
if(!data.after.val()){
console.log('Notification Deleted : ', notification_id)
return null;
}
const deviceToken = admin.database().ref(`/All_Users/${reciever_user_id}/Credentials/device_token`).once('value');
return deviceToken.then(result =>
{
const token_id = result.val()
const payload = {
notification:
{
title: "Coupon Used",
body: `Your Coupon has been used..!!`,
icon: "default"
}
}
return admin.messaging().sendToDevice(token_id, payload).then(
Response => {
console.log('Notification Sent')
}
)
})})
exports.sendNotification = functions.database.ref('/All_Users/{reciever_user_id}/UserApprovalNotifications/{notification_id}')
.onWrite((data, context ) => {
const reciever_user_id = context.params.reciever_user_id;
const notification_id = context.params.notification_id;
console.log('Notification sent to : ', reciever_user_id)
if(!data.after.val()){
console.log('Notification Deleted : ', notification_id)
return null;
}
const deviceToken = admin.database().ref(`/All_Users/${reciever_user_id}/Credentials/device_token`).once('value');
return deviceToken.then(result =>
{
const token_id = result.val()
const payload = {
notification:
{
title: "Profile Approved",
body: `Your Profile has been Approved..!!`,
icon: "default"
}
}
return admin.messaging().sendToDevice(token_id, payload).then(
Response => {
console.log('Notification Sent')
}
)
})})
Found the solution...as i am not javascript developer thats why i was struggling but the solution i found is pretty simple. just install the files to new folder.
exports.sendNotification = function.
the sendNotification is the name of function just change it and deploy it

On Deploying the Firebase Cloud Function getting an error of "Each then should return a value or throw"

I am new to Cloud Functions so I having issues with below code, the error is in the last part where the console.log is mentioned, please assist what shall I been done to deploy the Function successfully, as I am following a tutorial there is no such error for the name.
'use-strict'
const functions = require('firebase-functions');
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
exports.sendNotifications = functions.firestore.document("users/{user_id}/notifications/{notification_id}").onWrite(event => {
const user_id = event.params.user_id;
const notification_id = event.params.notification_id;
return admin.firestore().collection("users").doc(user_id).collection("notifications").doc(notification_id).get().then(queryResult => {
const from_user_id = queryResult.data().from;
const message = queryResult.data().message;
const from_data = admin.firestore().collection("users").doc(from_user_id).get();
const to_data = admin.firestore().collection("user").doc(user_id).get();
return Promise.all([from_data, to_data]).then(result => {
const from_name = result[0].data().name;
const to_name = result[1].data().name;
const token_id = result[1].data().token_id;
const payload = {
notification: {
title: "Notification from:" + from_name,
body: message,
icon: "default"
}
};
return admin.messaging().sendToDevice(token_id, payload).then(result =>{
console.log("notifcation sent");
});
});
});
});
By chaining your Promises and returning null in the last then(), as follows, you should solve your problem:
exports.sendNotifications = functions.firestore.document("users/{user_id}/notifications/{notification_id}").onWrite(event => {
const user_id = event.params.user_id;
const notification_id = event.params.notification_id;
return admin.firestore().collection("users").doc(user_id).collection("notifications").doc(notification_id).get()
.then(queryResult => {
const from_user_id = queryResult.data().from;
const message = queryResult.data().message;
const from_data = admin.firestore().collection("users").doc(from_user_id).get();
const to_data = admin.firestore().collection("user").doc(user_id).get();
return Promise.all([from_data, to_data]);
})
.then(result => {
const from_name = result[0].data().name;
const to_name = result[1].data().name;
const token_id = result[1].data().token_id;
const payload = {
notification: {
title: "Notification from:" + from_name,
body: message,
icon: "default"
}
};
return admin.messaging().sendToDevice(token_id, payload)
})
.then(messagingResponse => {
console.log("notification sent");
return null; //Note the return null here, watch the 3 videos about "JavaScript Promises" from the Firebase video series: https://firebase.google.com/docs/functions/video-series/
});
});
You may have a look at the corresponding MDN documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining
Also, note that, in your code, it seems that you are not using the to_name constant.

Cant send push in firebase .sendToDevice()

I'm simply trying to make a web push notifications work but I cant seem to get past the .sendToDevice() method, it runs but I dont receive any push notifications. Can someone please tell/show me what im doing wrong here...
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotifications = functions.database.ref('/notifications/{notificationId}')
.onWrite((change, context) => {
console.info("Running..");
// Only edit data when it is first created.
if (change.before.exists()) {
return null;
}
// Exit when the data is deleted.
if (!change.after.exists()) {
return null;
}
// Grab the current value of what was written to the Realtime Database.
const NOTIFICATION_KEY = context.params.notificationId
const NOTIFICATION_DATA = change.after.val();
const payload = {
notification: {
title: `New Message from ${NOTIFICATION_DATA.user}!`,
body: NOTIFICATION_DATA.message,
icon: NOTIFICATION_DATA.userProfileImg,
click_action: `https://google.com`
}
};
return admin.database().ref('/tokens').once('value').then((data) => {
if ( !data.val( ) ) return;
const snapshot = data.val();
const tokens = [];
for(let key in snapshot) {
tokens.push( snapshot[key].token);
}
console.info(tokens);
console.info(snapshot);
return admin.messaging().sendToDevice(tokens, payload);
})
});

How to access user profile information in firebase through getUser()

I am using cloud functions as a means to send users push notifications for my app. I am following the template set by google Here. The problem I have is that I dont really understand Javascript well and I have my user profile data stored within a profile node. When I call the getUser() function I am not able to access the user info within the profile node. How can I access the data within the users profile node so that I can display their "username" and "profileImage" in the push notifications.
Data Structure
users/uid/profile/Dictionary(key/val pairings here for data).
Google Data Structure
users/uid/displayName
Cloud Function:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendPushNotificationRep = functions.database.ref('/recieved-friend-requests/{userId}/{friendId}').onWrite(event => {
const userID = event.params.userId;
const friendID = event.params.friendId;
if (!event.data.val()) {
return;
}
const getDeviceTokensPromise = admin.database().ref(`/users/${userID}/fcmToken`).once('value');
// Get the follower profile.
const getRepProfilePromise = admin.auth().getUser(friendID);
return Promise.all([getDeviceTokensPromise, getRepProfilePromise]).then(results => {
const tokensSnapshot = results[0];
const friend = results[1];
if (!tokensSnapshot.hasChildren()) {
return console.log('There are no notification tokens to send to.');
}
const payload = {
notification: {
title: 'Rep Request!',
body: `${friend.username} sent you a request`,
badge: '1',
sound: 'default',
icon: 'logo3'
}
};
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);
});
});
});

Firebase Cloud Functions Does not work when used Promise.all

I have an Android app To organize events
I am trying to send a Notification to subscribers about the changes in time or date of the event.
When I used the following example, the function worked fine
//Cloud Functions Modules
const functions = require('firebase-functions');
//Firebase Admin SDK Modules (it will send the Notifications to the user)
const admin = require('firebase-admin');
//init Admin SDK
admin.initializeApp(functions.config().firebase);
exports.changeventTime = functions.database.ref('/user-
event/{authUid}/{key}/eventTime/')
.onWrite(event => {
var eventKey = event.params.key;
var authUid = event.params.authUid;
var eventSnapshot = event.data;
var newTime = eventSnapshot.val();
var eventTopic = "notifications_"+eventKey;
var payload = {
data: {
pushTyp: 'changTime',
time: newTime,
key: eventKey,
authuid: authUid
}
};
// Send a message to devices subscribed to the provided topic.
return admin.messaging().sendToTopic(eventTopic, payload)
.then(function (response) {
// See the MessagingTopicResponse reference documentation for the
// contents of response.
console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
But when I tried to use "return Promise.all()" The function did not work!
As in the following example:
//Cloud Functions Modules
const functions = require('firebase-functions');
//Firebase Admin SDK Modules (it will send the Notifications to the user)
const admin = require('firebase-admin');
//init Admin SDK
admin.initializeApp(functions.config().firebase);
exports.changeventTime = functions.database.ref('/uesr-
event/{authUid}/{eventKey}/eventTime/')
.onWrite(event => {
const eventKey = event.params.eventKey;
const authUid = event.params.authUid;
const eventTopic = "notifications_"+eventKey;
const eventSnapshot = event.data;
const newTime = eventSnapshot.val();
const getevent = admin.database().ref(`user-event/${authUid}/${eventKey}/`).once('value');
return Promise.all(getevent).then(results => {
const eventSnapshot = results[0];
const eventNumber = eventSnapshot.val().eventNumber;
const eventDescription = eventSnapshot.val().eventDescription;
const eventTime = eventSnapshot.val().eventTime;
const payload = {
data: {
pushTyp: 'changeTime',
time: eventTime,
key: eventKey,
authuid: authUid,
number: eventNumber,
dscr: eventDescription
}
};
// Send a message to devices subscribed to the provided topic.
return admin.messaging().sendToTopic(eventTopic, payload)
.then(function (response) {
// See the MessagingTopicResponse reference documentation for the
// contents of response.
console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
});

Categories

Resources