Reputation: 441
I am playing around with firebase cloud functions and I can't quite get it to run without an error. It keeps saying that userID is undefined.
Here is the structure for the database:
And here is the code I am running for the function:
exports.observeMentions = functions.database.ref('/notifications/{uid}/{notificationId}/mentioned').onCreate((snapshot, context) => {
var uid = context.params.uid;
var notificationId = context.params.notificationId;
return admin.database().ref('/notifications/' + uid + '/' + notificationId + '/uid').once('value', snapshot => {
var userUID = snapshot.val();
return admin.database().ref('/users/' + userID).once('value', snapshot => {
var userThatMentioned = snapshot.val();
return admin.database().ref('/notifications/' + uid + '/' + notificationId + '/uid').once('value', snapshot => {
var type = snapshot.val();
return admin.database().ref('/users/' + uid).once('value', snapshot => {
var user = snapshot.val();
if ((type = 3)){
var payload = {
notification: {
body: userThatMentioned.username + ' Mentioned you in a comment'
}
};
}else{
var payload = {
notification: {
body: userThatMentioned.username + ' Mentioned you in their post'
}
};
}
if (userUID != uid){
admin.messaging().sendToDevice(user.fcmToken, payload)
.then(function(response) {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch(function(error) {
console.log('Error sending message:', error);
});
}
})
})
})
})
})
Any help would be greatly appreciated!
Thank you
Edit/Attempt:
exports.observeMentioned = functions.database.ref('/notifications/{uid}/{notificationId}/mentioned').onCreate((snapshot, context) => {
var uid = context.params.uid;
var notificationId = context.params.notificationId;
return admin.database().ref('/notifications/' + uid + '/' + notificationId + '/uid').once('value')
.then(snapshot => {
var userID = snapshot.val();
return admin.database().ref('/users/' + userID).once('value');
})
.then(snapshot => {
var userThatMentioned = snapshot.val();
return admin.database().ref('/notifications/' + uid + '/' + notificationId + '/type').once('value');
})
.then(snapshot => {
var type = snapshot.val();
return admin.database().ref('/users/' + uid).once('value');
})
.then(snapshot => {
var user = snapshot.val();
if ((type == 3)){
var payload = {
notification: {
body: userThatMentioned.username + ' Mentioned you in a comment'
}
};
}else{
var payload = {
notification: {
body: userThatMentioned.username + ' Mentioned you in their post'
}
};
}
return payload
})
.then(snapshot => {
var payload = snapshot.val();
return admin.messaging().sendToDevice(user.fcmToken, payload);
})
.catch(error => {
console.log('Error sending message:', error);
});
});
This keeps getting the error:
Error sending message: ReferenceError: Type is not defined.
I don't understand why type is not defined?
Upvotes: 0
Views: 370
Reputation: 216
I think you have a scoping problem.
Your variables user
, userThatMentioned
, and type
are defined in the chained promises but are out of scope by the time you need to use them in later Promises.
I'd recommend declaring user
, userThatMentioned
, and type
up where you're defining uid
and notificationId
. That way these variables can be accessed anywhere inside your chained Promises. You don't even have to define them at that point, just hoist them up!
Likewise, the declaration of var payload
is only valid inside the scope of the if/else statement. I've corrected these scope problems so you can see the difference.
IMPORTANT
In the long-run you should definitely consider installing a linter in the code editor you use. It will catch these problems for you. My go-to, ESLint, underlines the problem and hovering over it will tell you exactly what's going on.
You also absolutely need familiarize yourself with the concept of scope because it's a very important part of writing successful code in any language.
Bonne chance!
const { firestore } = require("firebase")
const { functions } = require("firebase")
const admin = firestore.admin()
exports.observeMentioned = functions.database
.ref("/notifications/{uid}/{notificationId}/mentioned")
.onCreate((snapshot, context) => {
var uid = context.params.uid
var notificationId = context.params.notificationId
var user // HOISTED
var type // HOISTED
var userThatMentioned // HOISTED
return admin
.database()
.ref("/notifications/" + uid + "/" + notificationId + "/uid")
.once("value")
.then((snapshot) => {
var userID = snapshot.val()
return admin
.database()
.ref("/users/" + userID)
.once("value")
})
.then((snapshot) => {
userThatMentioned = snapshot.val()
return admin
.database()
.ref("/notifications/" + uid + "/" + notificationId + "/type")
.once("value")
})
.then((snapshot) => {
type = snapshot.val()
return admin
.database()
.ref("/users/" + uid)
.once("value")
})
.then((snapshot) => {
user = snapshot.val()
var payload // HOISTED
if (type == 3) {
payload = {
notification: {
body: userThatMentioned.username + " Mentioned you in a comment",
},
}
} else {
payload = {
notification: {
body: userThatMentioned.username + " Mentioned you in their post",
},
}
}
return payload // RETURNING AN OBJECT...
})
.then((payload) => { // ... TO THE NEXT PROMISE
return admin.messaging().sendToDevice(user.fcmToken, payload)
})
.catch((error) => {
console.log("Error sending message:", error)
})
})
Upvotes: 1
Reputation: 83048
There are several parts of your code that need to be corrected:
var userUID = snapshot.val();
and in the next line you use userID
(return admin.database().ref('/users/' + userID)
) => Hence the "Undefined" error.if
check you should use the equality operator (==
or ===
)once()
method, use the Promise version and chain the promises returned by the once()
method calls with then()
, as shown below.sendToDevice()
method. See the doc for more details on how important this last point is.exports.observeMentions = functions.database.ref('/notifications/{uid}/{notificationId}/mentioned').onCreate((snapshot, context) => {
var uid = context.params.uid;
var notificationId = context.params.notificationId;
return admin.database().ref('/notifications/' + uid + '/' + notificationId + '/uid').once('value')
.then(snapshot => {
var userID = snapshot.val();
return admin.database().ref('/users/' + userID).once('value');
})
.then(snapshot => {
var userThatMentioned = snapshot.val();
return admin.database().ref('/notifications/' + uid + '/' + notificationId + '/uid').once('value');
})
.then(snapshot => {
// ....
// return a Promise
})
.then(snapshot => {
// ....
return admin.messaging().sendToDevice(....);
})
.catch(error => {
// ...
});
});
Upvotes: 1