I have two functions that trigger onCreate
and onUpdate
however, the {uid}
in onUpdate
is returning undefined
, whilst onCreate
returns the {uid}
.
How can I get the {uid}
to work for onUpdate
?
onUpdate.f.js - {uid}
is undefined
exports = module.exports = functions.firestore
.document('users/{uid}/alerts/{name}') //UID is the User ID value stored in alerts
.onUpdate(snap => {
const user = snap.data();
console.log(user);
const msg = {
to: user.email,
from: '[email protected]',
templateId: user.template,
dynamic_template_data: {
firstName: user.firstName,
email: user.email,
id: user.uid
}
};
return sgMail.send(msg).catch(err => console.log(`${user.email} - ${err}`));
});
onCreate.f.js - {uid}
is correct
exports = module.exports = functions.firestore
.document('users/{uid}/alerts/{name}')
.onCreate(snap => {
const user = snap.data();
console.log(user);
const msg = {
to: user.email,
from: '[email protected]',
templateId: user.template,
dynamic_template_data: {
firstName: user.firstName,
email: user.email,
id: user.uid
}
};
return sgMail.send(msg).catch(err => console.log(`${user.email} - ${err}`));
});
Fields in doc
Alerts from frontend
doCreateAlert = (id, email, firstName, lastName, alertType, transactionEmailId) => {
const db = this.firestore;
return db.doc(`users/${id}/alerts/${alertType}`).set({
uid: id,
name: alertType,
email: email,
firstName: firstName,
lastName: lastName,
template: transactionEmailId,
dateCreated: new Date(),
dateModified: new Date()
});
};
The onUpdate is triggered by updating the database with onClick={this.updateAlert}
as
updateAlert = () => {
const { firebase, userID } = this.props;
const panyTypeSetup = db.doc(`users/${userID}/alerts/emailVerified`);
panyTypeSetup.update({
dateModified: new Date()
});
};
on the frontend I receive the error of
Uncaught (in promise) Error: No document to update: projects/app/databases/(default)/documents/users/undefined/alerts/emailVerified
and the function is never run. If I manually update the doc
in Firestore, I get an error in the firebase functions log as
TypeError: snap.data is not a function
at module.exports.functions.firestore.document.onUpdate.snap (/user_code/lib/auth/onUpdate.f.js:17:23)
at cloudFunctionNewSignature (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:105:23)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:135:20)
at /var/tmp/worker/worker.js:754:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
I have two functions that trigger onCreate
and onUpdate
however, the {uid}
in onUpdate
is returning undefined
, whilst onCreate
returns the {uid}
.
How can I get the {uid}
to work for onUpdate
?
onUpdate.f.js - {uid}
is undefined
exports = module.exports = functions.firestore
.document('users/{uid}/alerts/{name}') //UID is the User ID value stored in alerts
.onUpdate(snap => {
const user = snap.data();
console.log(user);
const msg = {
to: user.email,
from: '[email protected]',
templateId: user.template,
dynamic_template_data: {
firstName: user.firstName,
email: user.email,
id: user.uid
}
};
return sgMail.send(msg).catch(err => console.log(`${user.email} - ${err}`));
});
onCreate.f.js - {uid}
is correct
exports = module.exports = functions.firestore
.document('users/{uid}/alerts/{name}')
.onCreate(snap => {
const user = snap.data();
console.log(user);
const msg = {
to: user.email,
from: '[email protected]',
templateId: user.template,
dynamic_template_data: {
firstName: user.firstName,
email: user.email,
id: user.uid
}
};
return sgMail.send(msg).catch(err => console.log(`${user.email} - ${err}`));
});
Fields in doc
Alerts from frontend
doCreateAlert = (id, email, firstName, lastName, alertType, transactionEmailId) => {
const db = this.firestore;
return db.doc(`users/${id}/alerts/${alertType}`).set({
uid: id,
name: alertType,
email: email,
firstName: firstName,
lastName: lastName,
template: transactionEmailId,
dateCreated: new Date(),
dateModified: new Date()
});
};
The onUpdate is triggered by updating the database with onClick={this.updateAlert}
as
updateAlert = () => {
const { firebase, userID } = this.props;
const panyTypeSetup = db.doc(`users/${userID}/alerts/emailVerified`);
panyTypeSetup.update({
dateModified: new Date()
});
};
on the frontend I receive the error of
Uncaught (in promise) Error: No document to update: projects/app/databases/(default)/documents/users/undefined/alerts/emailVerified
and the function is never run. If I manually update the doc
in Firestore, I get an error in the firebase functions log as
TypeError: snap.data is not a function
at module.exports.functions.firestore.document.onUpdate.snap (/user_code/lib/auth/onUpdate.f.js:17:23)
at cloudFunctionNewSignature (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:105:23)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:135:20)
at /var/tmp/worker/worker.js:754:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
Share
Improve this question
edited Oct 24, 2018 at 18:42
Renaud Tarnec
83.2k10 gold badges97 silver badges129 bronze badges
asked Oct 24, 2018 at 18:33
DarrenDarren
2,29010 gold badges48 silver badges104 bronze badges
2 Answers
Reset to default 16As the guide shows, onUpdate
has two parameters: change
and context
. You use change
since you may want to access the value before the update or after the update. Assuming you want the value after the update, that would look like this:
exports = module.exports = functions.firestore
.document('users/{uid}/alerts/{name}') //UID is the User ID value stored in alerts
.onUpdate((change, context) => {
const user = change.after.data();
console.log(user);
const msg = {
to: user.email,
from: '[email protected]',
templateId: user.template,
dynamic_template_data: {
firstName: user.firstName,
email: user.email,
id: user.uid
}
};
return sgMail.send(msg).catch(err => console.log(`${user.email} - ${err}`));
});
Problem can easily be solved by reading the documents at Handle Event Data. However, if you are like me and skim the documents then the solution is
.onUpdate(change => {
const user = change.after.data();